ISPに関する記事を読むとき、ISPには2つの矛盾する定義があるようです。
最初の定義(参照によると1、2、3)、ISPは、インターフェイスを実装するクラスは、彼らが必要としない機能を実装することを強制されるべきではないと述べています。したがって、太いインターフェイスIFat
interface IFat
{
void A();
void B();
void C();
void D();
}
class MyClass: IFat
{ ... }
より小さなインターフェースに分割しISmall_1
、ISmall_2
interface ISmall_1
{
void A();
void B();
}
interface ISmall_2
{
void C();
void D();
}
class MyClass:ISmall_2
{ ... }
このよう以来、私のMyClass
唯一の方法、それが必要とする(実装することが可能であるD()
とのC()
またのためのダミー実装を提供することを余儀なくされることなく、) A()
、B()
およびC()
:
しかし、2番目の定義に従った(参照1、 2は、ナザールMerzaによって答えは、ISPはと述べている)MyClient
上のメソッドを呼び出しますMyService
上の方法を知っておくべきではないMyService
、それは必要としないこと。つまり、とMyClient
の機能のみが必要な場合、代わりにC()
D()
class MyService
{
public void A();
public void B();
public void C();
public void D();
}
/*client code*/
MyService service = ...;
service.C();
service.D();
私たちは分離する必要があります MyService's
メソッドをクライアント固有のインターフェイスにするます。
public interface ISmall_1
{
void A();
void B();
}
public interface ISmall_2
{
void C();
void D();
}
class MyService:ISmall_1, ISmall_2
{ ... }
/*client code*/
ISmall_2 service = ...;
service.C();
service.D();
したがって、前者の定義では、ISPの目標は「IFatインターフェイスを実装するクラスの寿命を短縮する」ことであり、後者の場合、ISPの目標は「MyServiceのメソッドを呼び出すクライアントの寿命を短縮する」ことです。
ISPの2つの異なる定義のうち、実際に正しいのはどれですか?
@MARJAN VENEMA
1。
したがって、IFatをより小さなインターフェイスに分割する場合、どのメソッドが最終的にどのメンバーであるかに基づいてISmallインターフェイスを決定する必要があります。
同じインターフェース内に凝集メソッドを配置することは理にかなっていますが、ISPパターンでは、クライアントのニーズがインターフェースの「凝集性」より優先されると考えました。言い換えると、ISPで特定のクライアントが必要とするメソッドを同じインターフェイス内にまとめる必要があると考えましたが、それは、そのインターフェイスから、まとまりのために同じインターフェイス内に置くべきメソッドを除外することを意味しますか?
したがって、そこにしかコールに必要するクライアントの多くがあった場合にCutGreens
はなく、またGrillMeat
、我々は唯一置くべきISPパターンに付着するCutGreens
内部ICook
もではなく、GrillMeat
2つの方法が非常に粘着性であっても、!
2。
あなたの混乱は、最初の定義に隠された仮定、つまり実装クラスがすでに単一の責任原則に従っているという隠された仮定から生じていると思います。
「SRPに従っていないクラスを実装する」とは、実装IFat
するクラスまたはISmall_1
/ を実装するクラスを指しISmall_2
ますか?私はあなたが実装するクラスを参照していると仮定しますIFat
か?もしそうなら、なぜ彼らはまだSRPに従っていないと思いますか?
ありがとう