2017-01-28 17 views
3

私はSOLID原則について読んでいると私は、オブジェクトがすでに構図を意味葯オブジェクトにインスタンス化さ渡さなければならないことを意味する「依存関係逆転の原則」にここに停止する依存関係の反転を適用することはできません原則ですか?または私は何かが恋しい? UPDATE ************************************************** ** は、クラスを持っており、このクラスが葯オブジェクトへの参照である属性を持って、私たちは(私にとっては)2溶液があるとします。依存性逆転原理と組成

  1. クラス外でオブジェクトを作成し、クラスに渡します(依存関係)
  2. クラスの内部にオブジェクトを作成します。それはself(構図)です。

ありがとうございます。

+0

ここに矛盾はありません。オブジェクトは、コンストラクタで渡されるいくつかの他のオブジェクトで構成されています。何ですか? –

+0

私はクラス間の依存関係とオブジェクト間の依存関係を混在させていると思います。もちろん、合成オブジェクトはそのコンポーネントに依存します。しかし、抽象化(インターフェイス)を使用している場合は、クラス間に依存関係があるということではありません。 –

+0

@FrankPuffer依存性注入を使用して合成を使用できますか? – justsomedev

答えて

6

あなたの混乱はあなたの構成の理解から来ます。別のオブジェクトが所有するオブジェクトは、所有するオブジェクトの存続期間に依存します。これは所有するオブジェクトを所有するクラス内に作成しなければならないという意味ではありません。

クラスにオブジェクトを作成した場合、このクラスは作成されたクラスと緊密に結合されています。他のクラスを作成するクラスを変更せずに実装を交換することはできません。

例:あなたは、クラスのサーバーを使用するクラスのクライアントを、持っている上の写真で enter image description here

。これはコンポジションであり、クライアントにはタイプServerという属性があります。

あなたは、クライアントクラスの内部クラスサーバーのインスタンスを作成した場合、それは次のようになります。

public class Client { 
    private Server server; 

    public Client(){ 
     this.server = new Server(); 
    } 
} 

は今、あなたはサーバーの実装を交換したいと言うことができます。 Clientクラスの実装を変更する必要があるのは、それを交換する唯一の方法は別のクラス(AnotherServerと呼ばれることもある)のインスタンスを作成することだからです。

public class Client { 
    private AnotherServer anotherServer; 

    public Client(){ 
     this.anotherServer = new AnotherServer(); 
    } 
} 

これは、クライアントクラスがクラスサーバーに強く依存していることを示しています。

サーバの使用されている実装を簡単に変更し、クライアントの動作を変更するには、抽象クラス(抽象クラ​​スまたはインタフェース)からクライアントを構成する方がよいでしょう。そうすることで、具象クラスのみを作成できるので、所有するクラスで必要なオブジェクトを作成することはできません。クラスの作成とは、コンストラクターを呼び出し、作成されたクラスに依存することを意味します。

コンポジションを達成するためのよりよい方法(クライアントはサーバーから構成されます)は、セッターメソッドまたはコンストラクターを使用して注入することです。このように、インターフェイスの背後に実装クラスを隠すことができます。

例:私たちはサーバーの具体的な実装についての知識からクライアントを保護する二絵で enter image description here

。それはサーバーインターフェイスに依存します。この依存関係は、クライアントがインターフェイスを定義するため、劇的なものではありません。彼は、Serverインターフェイスの必要な機能について決定します。サーバのインタフェースがクライアントに属していることを示すために、それを「ClientServer」と呼ぶ。

クライアントを作成するには、クラス外のClientServerインターフェイス用の具体的なクラスを作成し、コンストラクタまたはセッタメソッドを通じて注入する必要があります。このよう

... 
FirstServer first = new FirstServer(); 
Client client = new Client(first); 

client.setServer(new SecondServer()); 
... 

あなたは簡単にも、実行時に、クライアントで使用されるサーバーの実装を交換することができます。

このメカニズムは、依存性反転の原理(DIP)と呼ばれます。しかし、なぜ? Clientクラスは引き続きサーバーインターフェイスに依存しています。インタフェースが変更された場合、クライアントも変更する必要があります。はい、これは正しいです。しかし、クライアントは、彼がそのインタフェースで必要とする機能を決定します。したがって、通常、クライアントは変更が必要だと言ったときにインタフェースが変更されます。クライアントが変更されるため、インタフェースが変更されます。

具体的なサーバー "FirstServer"と "SecondServer"はClientServerインターフェイスを実装しているため、そのインターフェイスにも依存しています。継承はコンポジションよりも依存性が強いため、具体的なサーバークラスはClientクラスよりもインターフェイスに依存しています。

これは、依存関係が逆転している理由です。具体的なサーバークラスは、現在、 "Client-ClientServer" -conglomerateに依存しています。

あなたの質問に対する答えは次のとおりです。別のクラスにクラスを作成するときにDIPに到達することはできません。しかし、このインターフェースを継承する具象クラスを注入するインターフェースを定義することによって、DIPに到達することができます。

+0

.NET Frameworkからクラスを使用する必要がある場合。それをクラスに注入する必要がありますか? – VansFannel

1

from Wikipediaを撮影:

A.ハイレベルのモジュールは、低レベルのモジュールに依存してはなりません。どちらも抽象に依存するはずです。

B.抽象は詳細に依存してはいけません。詳細は抽象化に依存する必要があります。

そして、あなたが言った:

をオブジェクトがすでに

依存関係逆転原理はクラスのコンストラクタなどのプログラミング実装の詳細に対しては何もしてい別のオブジェクトにインスタンス化さ渡さなければならないことを意味しますこれは、構築されているオブジェクトを初期化するためのものです。 アブストラクションではなく、実装として型指定されたコンストラクタパラメータを定義していない場合、および/または注入される依存関係がターゲット依存関係よりも上位層の場合は、全体の原則に違反しているわけではありません。

+0

なぜ私は私の答えを改善するためにdownvoteを得たかを知ることは素晴らしいことです。ありがとう。 –

関連する問題