2012-08-01 20 views
5

私は最近Robert.C.Martinの優れた本「Agile Principals、Patterns and Practices in C#」のDependency-Inversion Principalについて読んでいます。しかし、私が完全に理解していないと感じるこのプリンシパルの側面があります。依存関係が変更された場合、依存モジュールを変更する必要性がどのように低減されますか?

Robertは、上位モジュールが下位モジュールに依存する場合、下位モジュールの変更によって上位モジュールも変更される可能性があることを説明しています。彼は次の例でこれを示しています。ロバートは言うこのコードについて

public class Button 
{ 
    private Lamp lamp; 
    public void Poll(){ 
     if(/*some condition*/) 
     Lamp.TurnOn(); 
    } 
} 

「Buttonクラスは、ランプのクラスに直接依存し、この依存性は、ボタンはランプへの変更によって影響を受けるであろうことを意味します。」

1)私たちは、クラスのが、パブリックインターフェイスに影響を与えることなく、内部実装を変更することがあります。我々はランプのクラスになるかもしれない変更の2つの可能性のある種類があり、私はそれを見たよう

2)TurnOnメソッドにパラメータを渡すようにパブリックインターフェイスを変更することがあります。

私が理解していないことは、最初のケースではなぜ変更によってButtonクラスが変更されるのでしょうか? Lampへのパブリックインターフェイスは変更されていませんが、なぜボタンを変更する必要がありますか?

2番目のケースでは、これでボタンを変更する必要があることがわかります。しかし、この場合、抽象化に応じてどのように変化するでしょうか?確かに、もし私がLampへのインタフェースを変更する正当な理由があるなら、LampとButtonが依存する抽象化のインタフェースも変更するでしょう。このケースでは、それに依存する抽象化が変更されたため、ボタンを変更する必要があります。

高水準モジュールの再利用性、高水準モジュールによるインターフェイスの所有権、実行時の依存関係の実装を選択する能力など、DIPには他にも利点があることに気付きましたが、DIPの削減方法下位レベルのモジュールへのインタフェースが変更されたときに変更する依存モジュールの必要性、および/または従属モジュールの内部変更が上位モジュールの変更を引き起こす原因は何か。

答えて

1

DIPがこの例にもたらす重要な違いは、インターフェイスの所有権だと思います。特に、ボタンがクライアントであり、ランプがサーバーであるインターフェースを所有する層。

具体的なクラスLampへの依存関係では、インタフェース(.TurnOn())はLampクラス(サーバー)によって所有されています。したがって、メソッドを所有しているサーバーのニーズだけに基づいて.TurnOn()メソッドを変更することができます。これにより、その後Buttonクラス(クライアント)に変更する必要があります。

インターフェイスがISwitchableDeviceインターフェイス/抽象クラスに抽象化される場合、所有権はクライアントまたは共有レイヤに転送されます。したがって、インタフェースの変更はサーバーのニーズによって直接駆動することはできません.Interfaceを変更せずに(サーバーが所有する)Lampクラスの変更を行うことができます。また、ISwitchableDeviceインターフェイスへの変更が必要な場合は、これがクライアントまたは共有レイヤのニーズに基づいて行われます。

0

たとえば、インタフェースに関しては、(パブリックインタフェースの一部である)Lampのコンストラクタに変更が加えられ、抽象ベースまたはインタフェースに依存している場合、それらの変更はボタンの実装(あなたがそこにそれを構築する場合を除き、それは部分的に別の問題です)。
"純粋な実装"に関しては、どのような種類のインタフェースにも変更が加えられていない(コンストラクタ、スローされうる例外など)、共通のグローバル依存関係が変更されていない適切にカプセル化された設計では、だからそれは問題ではありません。

基本的には、これらの問題に関しては、表面積を減らすため、具体的な内容は少なくなりますが、いくつかの詳細が常に必要となります。

抽象化が役に立たないかどうか分かりませんかどうかは、大文字と小文字を区別する必要があります。

+0

ありがとうダニエル。私は具体的なサービスのコンストラクタを変更することは、インターフェイスに依存して、依存するクラスを変更から隔離する例です(しかし、それは構築をしないと仮定しています)。 Robertは彼の記事で推移的である依存について話しています:もしA→BとB→Cならば、クラスCの変更はクラスB_とクラスA_の変更を強制することができます。私はまだこれがどういう場合になるかはまだ分かりません。 Cの公開インターフェースを変更したとしても、なぜAに影響しますか? – John

+0

クラスcが新しい依存関係を取得し、その依存関係がクラスbでは利用できないが、aで利用できる場合、aはその依存関係をbに提供しなければならない可能性があるので、bはそれをc – Daniel

関連する問題