【SOLID原則】単一責任の原則とは何か

2023/02/26に公開約1,500字

※読了目安時間:3分

SOLID原則のSに当たる部分ですね。
ではSOLID原則にはどのようなものがあるのでしょうか?

SOLID原則とは

SOLID原則は、オブジェクト指向設計において、柔軟で保守可能なコードを実現するための5つの原則の総称です。以下がそれぞれの原則の略称と説明です。

  • SRP(単一責任の原則):各クラスは、1つの責務のみを持つべきです。
  • OCP(開放・閉鎖の原則):拡張には開かれ、修正には閉じているべきです。
  • LSP(リスコフの置換原則):サブタイプは、常にその基本型に置き換えることができます。
  • ISP(インターフェイス分離の原則):必要のないインターフェイスへの依存を回避するために、クライアントは、必要な機能のために必要なインターフェイスのみを使用するべきです。
  • DIP(依存性逆転の原則):高水準のモジュールは、低水準のモジュールに依存すべきではありません。両方のモジュールは、抽象化に依存すべきです。

これらの原則を遵守することで、コードの理解性や保守性が高くなり、大規模開発においても柔軟に対応できるようになります。

単一責任の原則とは

上記の原則について解説していきます。
単一責任の原則とは、各クラスが1つの責務のみを持ち、その責任を完全に負うべきであるという原則です。
複数の責務を持つクラスが存在すると、それらの責務が密接に関連しているため、1つの責務を変更すると、他の責務にも影響が及ぶ可能性があります。
単一責任の原則を遵守することで、責任が明確に分離され、変更の影響範囲を限定することができます。

単一責任の原則に違反している例をみてみましょう

class User {
  // ユーザ情報関連の責務
  getUserName() {
    // ...
  }

  getEmail() {
    // ...
  }

  // 認証関連の責務
  login() {
    // ...
  }

  logout() {
    // ...
  }

  // 支払い関連の責務
  makePayment() {
    // ...
  }
}

上記の例の場合、Userクラスがどのような責務(仕事)を担当しているのか理解することが難しくなりますし、各責任に対するテストを書くことも難しくなります。
また再利用性も悪くなりますね。例えばUserとは別にOwnerというクラスを作ったとします。Ownerクラスでも認証の機構は同じロジックなので使いまわしたいが、Userクラスに定義されているために呼び出しが困難になることが考えられます。(認証の機能を呼ぶためにUserのインスタンスや静的メソッドを呼ぶのが変ですよね)

単一責任の原則を遵守するためには、 User クラスを3つのクラスに分割することができます。

class UserProfile {
  getUserName() {
    // ...
  }

  getEmail() {
    // ...
  }
}

class Auth {
  login() {
    // ...
  }

  logout() {
    // ...
  }
}

class UserPayment {
  makePayment() {
    // ...
  }
}

これにより、各クラスが1つの責務のみを持つようになり、変更の影響範囲を限定することができます。
OwnerクラスもAuthクラスを使う形になるので自然に理解できるコードになりました。

Discussion

ログインするとコメントできます