単一責任の原則(SRP)

SRP:The Single Responsibility Principle

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

2つ以上存在すると何が良くないのか?
通常、仕様変更が発生すると、クラスの役割が変化する。
このとき、クラスの役割が1つであれば、どのように変化したのかをみれば変更部分が浮き彫りになる。
しかし、クラスの役割が複数存在すると、クラスを変更する理由も複数存在することとなり、変更の経緯が読み取りづらく、また変更箇所もぼやけてしまう。
その結果、ある役割の変更により関係のない他の役割が影響を受け、予想もしない不具合を生む可能性も出てくる。

役割とは?

単一責任の原則(SRP)では、「役割(責任) = 変更理由」と定義している。
つまり、クラスを変更するのに2つ以上の理由がある場合、それは2つの役割を担っていると考えられる。

しかし、2つ以上の役割を担っているか判断することは非常に難しいことである。

次の例では、一見問題がないように見えるが2つの役割を担っている。

interface Modem {
	public void dial(String pno);
	public void hangup();
	public void send(char c);
	public char recv();
}

dial(),hangup()は、「接続の管理」を担っており、send(),recv()は「データ通信」の役割を担っている。
このような場合、例えば接続する際に認証が必要な形に変更されるのであれば、2つの役割を分けるべきと考えることができる。
しかし、そうでないのなら不必要に複雑な構造となってしまう為、分離しない方が良いといえる。

結局のところ、「変更の理由が変更の理由たるのは、実際に変更の理由が生じた場合だけである。」との言葉にある(らしい)ように、単一責任の原則を適用する場合は変更の予兆が発生してからというやり方が賢明である。

永続性のあるシステムと単一責任の原則

あるクラスがビジネスメソッドと永続データを縫合しているとしたら、2つの役割を担っていることになる為、絶対にするなとのこと。
理由は、ビジネスルールは頻繁に変化するものであり、また永続データもビジネスルールとはまったく異なる理由で変更されることがある為。

でも・・・

それをいったら、ドメインオブジェクトではなくトランザクションスクリプトで設計するか、もしくはドメインオブジェクトでProxyパターンや例えばGeneration Gapパターンを使えと言っていることにならないのか・・・
なにかイマイチ納得できない。。