【SOLID】単一責任原則~変更する理由は、ただひとつだけ

single-responsibility-principle
単一責任原則

Single Responsibility Principle

クラスを変更する理由はひとつ以上存在してはならない

クラスをどう定義するか、の原則です。

SOLID原則と呼ばれる、主要5原則のひとつ。

SOLID原則
目次

どんなときに使える?

メソッド数が恐ろしく多いとき

新人くん

〇〇クラス、メソッド5個分の実装終わりましたー

イケイケくん

〇〇クラスのメソッド10個追加完了っす!

リーダーさん

なんかこのクラス、メソッド100個くらいあるんだけど…

プログラム開発をしていると、やたら大きいクラスが登場したりします。メソッドがなん十個もあったり、1万行くらいのコードになったり…

こういうのはたいてい、あまり深い考えなしに、主力クラスに処理をぶちこんでいる状態

クラスを分けておかないと、今後の開発で支障が出そうです。でもどう分ければいいんでしょう?

クラス分割の指針=変更理由はひとつだけ

単一責任原則は、クラスをどう分割するかの指針になります。

それは「そのクラスの変更理由が1つだけ」になるよう、分割することです。

具体的な例で考えましょう。

従業員クラスの例

従業員のデータを管理するクラスを考えます。

// 従業員クラス
public class Employee {
  // 給与計算を行う
  public Money calculatePay() {
    ...
  }
  // 作業時間報告書を出力する
  public String reportHours() {
    ...
  }
  // データベースに保管する
  public void save() {
    ...
  }
}

このクラスには3つのメソッドがあります。

従業員クラスのメソッド
  • calculatePay 従業員の給与を計算します
  • reportHours 従業員の作業報告書を出力する
  • save 従業員に関する情報をデータベースに保管します

いずれも従業員のデータを操作するメソッドなので、従業員クラスにあるのが望ましい…本当でしょうか?

変更理由が多いクラス

問題なのは、3つのメソッドが、まったく違った理由で変更される可能性があることです。

メソッドの変更理由
  • calculatePay 給与計算に関わるルールが変わったら、修正が必要
  • reportHours レポートのフォーマットが変わったら、修正が必要
  • save データベーススキーマが変わったら、修正が必要

これら3つの変更は、おそらく別々の理由、別々のタイミングで、発生するでしょう。

そしてどの変更であっても、従業員クラスの変更が必要になってしまいます。

このような、あまりにも多くを知るクラスを、神クラス(God Class)といいます。

変更するということは、動かなくなる可能性がある、ということです。できるだけ1つのクラスは、変更機会が少ないほうがよいのです。

従業員クラスを分割する

では、クラスをどう分割すればよいでしょう?

そう、変更される可能性ごとに分けるのです。

// 従業員クラス
public class Employee {
  // 給与計算を行う
  public Money calculatePay() {
    ...
  }
}
// 従業員報告書クラス
public class EmployeeReporter {
  // 作業時間報告書を出力する
  public String reportHours(Employee e) {
    ...
  }
}
// 従業員リポジトリクラス
public class EmployeeRepository {
  // データベースに保管する
  public void save(Employee e) {
    ...
  }
}

これで、変更理由に対する改修箇所は、こうなります。

変更理由
  • 給与計算に関わるルールが変わったら……従業員クラスを修正
  • レポートのフォーマットが変わったら……従業員報告書クラスを修正
  • ベーススキーマが変わったら……従業員リポジトリクラスを修正

各々のクラスで、変更理由がひとつになりました。

それぞれのクラスの責任が単一となったわけです。

責任分割を考えるコツ=何に責任を持たないか?

単一責任とはいっても、「責任」をどう考えるのかは、とても難しいです。人により言うことは変わるし、状況によっても捉え方は違います。

単一責任について、ひとつ考えかたのコツがあります。

責任を考えるとき、逆に

このクラスは、なにに責任を持たないのか?

と考えるのです。

従業員クラスは、

  • 報告書フォーマットに依存しないし
  • DBのスキーマも決めるべきでない

であるなら、その処理は従業員クラスに実装すべきではないのです。

まとめ

単一責任原則の本質は、クラスだけでなく、関数やメソッドといったあらゆる要素で同じです。

「変更する理由は、ただひとつだけ」。その定義はとても難しいです。

でも、ちゃんと「変更する理由」を考えて、誰かに説明できるようにしておきましょう。それでクラスの責任はかなりクリアになるはずです。

SOLID原則
よかったらシェアしてね!
  • URLをコピーしました!
  • URLをコピーしました!
目次