ウィキペディアから:
単一責任の原則は、すべてのクラスが単一の責任を持つべきであり、その責任はクラスによって完全にカプセル化されるべきであると述べています。
複数のインターフェイスを実装すると、この原則に違反するということですか?
ウィキペディアから:
単一責任の原則は、すべてのクラスが単一の責任を持つべきであり、その責任はクラスによって完全にカプセル化されるべきであると述べています。
複数のインターフェイスを実装すると、この原則に違反するということですか?
それ自体ではないと思います。クラスは 1 つの責任を持つことができますが、そのプロセスで複数のことを行い、その責任を果たすために必要な一連のことごとに 1 つのインターフェイスを実装します。
また、Java のインターフェースを使用して、クラスが持つプロパティ (たとえば、Comparable
およびSerializable
) について説明することはできますが、実際にはクラスの責任については何も説明しません。
ただし、クラスが複数のインターフェースを実装し、それぞれが 1 つの責任に対応する場合、それはその原則に違反します。
たぶん、しかし必ずしもそうではありません。
インターフェイスは責任を負いません。インターフェースを、アプリケーション内でオブジェクトが果たす役割を定義するものと見なす、非常に強力なアーキテクチャ モードがあります。
それが何を意味するか考えてみてください。あらゆる種類のインターフェイスを持つクラスを持つことができPerson
ます (名前付けには .net 規則を使用しましょう)
class Person : IAmAStudent, IDrawSocialSecurity, IAmACitizen {
public SocialSecurityNumber getSocialSecurityNumber() {
return this.ssn;
}
private SocialSecurityNumber ssn;
public Person(SocialSecurityNumber ssn) { this.ssn = ssn; }
}
明らかに、これは SRP に違反することはありません。変更の理由は明らかに1 つだけです。人々と社会保障番号の関係が変わる場合です。しかし、オブジェクトは多くのインターフェイスを実装し、アプリケーションでいくつかの役割を果たします。
さまざまな機能を公開する複数のインターフェイスを実装している場合、SRP に違反している可能性がありますが、それも判断材料になる可能性があります。単一責任の原則は、疎結合を実現するための優れた経験則ですが、それだけが理想というわけではありません。また、関連するコードが一緒に存在する必要があることを示す高い凝集性もあります。この 2 つは基本的に相容れないものです (ただし、多くの場合、適切なバランスを実現する方法はあります)。したがって、どちらか一方の方向を合理的に選択し、意識的に SRP に違反することを決定する可能性があります。
最終的に、SRP とすべての SOLID ルールは、毎回盲目的に従うことではなく、特定の方針に沿って考えるようにすることを目的としています。
「単一責任」は、抽象化のレベルによって異なります。たとえば、複雑なシステムは、システムレベルで考えると、1つの責任がある場合があります。たとえば、テレビシステムの責任はビデオ画像を表示することです。次の下位レベルでは、そのシステムはサブシステム、モニター、電源ユニットなどで構成されています。このレベルでは、これらのユニットのそれぞれに独自の責任があります。
同様に、あるレベルのクラスは単一の責任を持っていると見なすことができます。ただし、下位レベルでは、ジョブの一部を実行する他の構成モジュール(クラス、インターフェースなど)が含まれている場合があります。たとえば、Studentクラスの責任は、学生の抽象化を表すことです。ただし、学生の住所を表す別のユニット(クラス)がある場合があります。
このように、複数のインターフェースを使用すること自体は、オブジェクト指向の原則に違反しません。