依存関係の反転の原則
定義
A.高レベルのモジュールは低レベルのモジュールに依存しないでください。どちらのタイプのモジュールも、抽象化に依存する必要があります。
B.抽象化は詳細に依存するべきではありません。詳細は抽象化に依存する必要があります。
最初の定義には、「モジュール」の概念が含まれています。これは非常に重要な概念であり、それなしではDIPを理解することはできません。
モジュール-論理的に相互接続された機能要素のセット
誤解を避けるために、例による定義を検討してください。読んだ本のリストを取得してユーザーに表示する必要があるとしましょう。このために、BooksInteractorクラスとBooksRepositoryクラスを使用します。これらの各クラスを、それぞれモジュールBIとBRに配置します。BooksInteractorクラスモジュールは、BooksRepositoryクラスに依存しています。
BooksInteractorは、BooksRepositoryから書籍のリストを取得する必要があります。 Interactorは、リポジトリがこのデータをどのように受信するかをまったく気にしません。つまり、この場合、BooksInteractorはBooksRepositoryの抽象化です。 2番目の定義によると、BooksInteractor(抽象化)はBooksRepository(実装)に依存するべきではありません。一方、リポジトリはBIモジュールについて知っている必要があります。では、何が起こるのでしょうか。インタラクターはリポジトリ内にある必要がありますか?いいえ、依存関係を反転するには、BooksRepositoryをIBooksRepositoryインターフェイスでカバーし、このインターフェイスをBooksInteractorクラスモジュールに配置する必要があります。それでは、DIPの最初の定義に戻って、図を見てみましょう。
見てください、上位モジュール(BIモジュール)は下位モジュール(BRモジュール)に依存していません。また、両方のモジュールは(IBooksRepositoryインターフェイスからの)抽象化に依存しています。リポジトリをインターフェイスでカバーすることで依存関係の反転の魔法を理解した場合は、依存関係の反転の原則を理解できます。おめでとう!あなたが理解する最も難しい部分。DIPの詳細については、Habréのこの記事をご覧ください。
制御の反転
「依存性反転原理」の概念を研究しました。次に、別の反転、つまり制御の反転に移りましょう。概念自体は非常に広範であり、プログラミングでは次の3つのいずれかを意味します。
- インターフェイスの反転-モジュール間の関係の中間インターフェイスへの委任。それはどこに適用されますか?たとえば、以前に調査したDIPでは。
- — (, DI/IOC ).
- — , . , , — Android . Activity Fragment, .
Dependency Injection
依存関係の挿入は、その依存関係をクラスに渡すためのメカニズムです。別のクラスに依存関係を渡す必要がある場合は、常にこれに遭遇します。依存関係を注入する方法はいくつかあります。コンストラクター(Constructor Injection)、メソッド(Method Injection)、およびプロパティ(Property Injection)です。これらの各メソッドは、独自の目的で使用されます。ただし、ここでは、依存関係インジェクションが依存関係をコンストラクター、メソッド、またはプロパティに渡すだけであることを理解することが重要です。
エッジケースの検討
- IoCとDIPなしでDIが存在する可能性はありますか?多分そうだね。具体的なクラスAのインスタンスを作成し、コンストラクター、メソッド、またはプロパティを介してクラスBのオブジェクトに渡します。
- IoCなしでDIPはありますか?いいえ、DIPはIoCでインターフェイス反転を実装する1つの方法です。
- DIなしのDIPはありますか?はい、下のモジュールをインターフェースに結び付けることができます。上位モジュールクラスはインターフェイス抽象化で機能しますが、下位モジュールクラスの具体的な実装は、上位モジュールのコンストラクターで作成されます。
DIP、DI、IoCの違いは、他の著者のこことここで確認できます。
コメントやフィードバックをいただければ幸いです。