5

私は最近、Robert.C.Martinの優れた本AgilePrincipals、Patterns and Practices in C#の依存性逆転の原則について読みました。しかし、この原則には、私が完全には理解していないと感じる側面が1つあります。

ロバートは、高レベルのモジュールが低レベルのモジュールに依存している場合、低レベルのモジュールを変更すると、高レベルのモジュールも変更される可能性があると説明しています。彼は次の例でこれを示しています。

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

このコードについてRobertは、「ButtonクラスはLampクラスに直接依存しています。この依存関係は、ButtonがLampへの変更の影響を受けることを意味します」と述べています。

私が見ているように、Lampクラスに加える可能性のある変更には2つの種類があります。

1)パブリックインターフェイスに影響を与えずに、クラスの内部実装を変更したい場合があります。

2)パブリックインターフェイスを変更して、TurnOnメソッドにパラメータを渡すことを決定する場合があります。

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

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

高レベルのモジュールの再利用性、高レベルのモジュールによるインターフェイスの所有権、実行時に依存関係の実装を選択する機能など、DIPには他にも利点があることを認識していますが、DIPが依存の必要性をどのように減らすかを理解するのに苦労しています下位レベルのモジュールへのインターフェイスが変更されたときに変更するモジュール、および/または依存モジュールの内部変更が上位レベルのモジュールの変更を引き起こす可能性がある理由。

4

2 に答える 2

1

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

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

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

于 2012-08-22T13:08:02.603 に答える
0

たとえば、インターフェイスに関して、Lampのコンストラクター(パブリックインターフェイスの一部)に変更が加えられ、抽象ベースまたはインターフェイスに依存している場合、それらの変更はボタンの実装に反映されません。 (そこで構築する場合を除きますが、それは部分的に別の問題です)。
「純粋な実装」に関しては、適切にカプセル化された設計で、インターフェイスに変更が加えられず(コンストラクター、スローされる可能性のある例外など)、共通のグローバル依存関係が変更されていないため、呼び出し元に影響を与えることはありません。それほど問題ではありません。

基本的に、これらの問題に関しては、表面積を減らしているので、いくつかの詳細は常に必要ですが、より少ない詳細に依存しています。

抽象化が役に立たない雑然としたものであるか、かけがえのない分離であるかどうかにかかわらず、それはケースごとに決定する必要があります。

于 2012-08-01T09:05:42.253 に答える