依存関係逆転の原則
高レベルのモジュールは低レベルのモジュールに依存すべきではありません。どちらも抽象化に依存する必要があります。
抽象化は詳細に依存すべきではなく、詳細は抽象化に依存する必要があります。
例を通して 高レベル モジュール と 低レベル モジュール を理解しましょう:
Flipkart のような e コマース アプリでは、高レベルで ProductCatalog、PaymentProcessor、CustomerProfile に分類できます (これらは主要なビジネス機能の一部です)
これらのビジネス機能は、上の図に示されている他のモジュールに相互依存しています。
注: 上のモジュールは、高 レベル モジュールと呼ばれるビジネス機能に近いものです。
下部のモジュールは、低 レベル モジュールと呼ばれる実装の詳細に近いものです。
低レベル モジュールは、SQLProductRepository、GooglePayService、WireTransfer、EmailSender、および VoiceDialer です。
CustomerProfile (高レベル モジュール) と通信モジュールだけを考慮すると、通信は低レベル モジュールですが、通信、EmailSender、および VoiceDialer だけを考慮すると、通信は高レベル モジュールになり、EmailSender とVoiceDialer は低レベルのモジュールです。
ここでのポイントは、高レベルおよび低レベル モジュールの概念は絶対的なものではなく、相対的なです。
上の画像によると、ProductCatalog は SQLProductRepository に依存しています。つまり、高レベルのモジュールは低レベルのモジュールに依存していますが、これは直接DIP の最初の定義と競合します。
ProductCatalog → SQLProductRepository の関係を取り上げ、さらに分析してみましょう。
import java.util.List; /* * High-Level module */ public class ProductCatalog { public void listAllProducts(){ SQLProductRepository sqlProductRepository = new SQLProductRepository(); List<String> allProductsNames = sqlProductRepository.getAllProductNames(); //Display all products names } }
/* * Low-level module */ import java.util.Arrays; import java.util.List; public class SQLProductRepository { public List<String> getAllProductNames(){ return Arrays.asList("soap","toothpaste"); } }
ProductCatalog は SQLProductRepository に直接依存しているため、これは明らかに DIP 定義 1 の違反です (定義によれば、高レベルと低レベルのモジュールは両方とも抽象化に依存する必要があります)
定義 1 に従ってこれを修正しましょう:
インターフェース ProductRepository の作成
import java.util.List; public interface ProductRepository { public List<String> getAllProductNames(); }
SQLProductRepository でのこのインターフェイスの実装
/* * Low-level module */ import java.util.Arrays; import java.util.List; public class SQLProductRepository implements ProductRepository{ @Override public List<String> getAllProductNames(){ return Arrays.asList("soap","toothpaste"); } }
最後に、高レベル モジュール ProductCatalog については、その中で SQLProductRepository を直接インスタンス化すべきではありません。同じ
に ProductFactory クラスを使用します。
public class ProductFactory { public static ProductRepository create(){ return new SQLProductRepository(); } }
ProductFactory を使用して SQLProductRepository をインスタンス化します
/* * High-Level module */ import java.util.List; public class ProductCatalog { public void listAllProducts(){ ProductRepository productRepository = ProductFactory.create(); List<String> allProductsNames = productRepository.getAllProductNames(); //Display all products names } }
参照オブジェクトは ProductRepository であることに注意してください。そのため、SQLProductRepository との密結合はありません
変更後の新しい依存関係は次のようになります
上記の変更は DIP 定義 1 によるものです。
上記のコード変更は、DIP の 2 番目の定義にも準拠しています。つまり、抽象化は詳細に依存すべきではなく、詳細は抽象化に依存する必要があります。
上の画像からわかるように、SQLProductRepository は ProductRepository に依存しており、その逆ではありません。 これが、この原則が依存関係逆転の原則と呼ばれる理由です
依存関係の注入 VS 依存関係の反転
Even though they are related, they are not the same and can not be used interchangeably
依存性の注入について:
ProductCatalog では、Factory メソッド ProductFactory.create() を使用して SQLProductRepository オブジェクトのインスタンスを取得します。
インスタンス作成プロセスはファクトリ クラス ProductFactory に委任されますが、初期化プロセスは依然として ProductCatalog クラスで行われます。
理想的には、ProductCatelog クラスがインスタンス化をいつどのようにトリガーするかについて心配する必要はありません。
インスタンス化された ProductRepository クラスを、要求されなくても ProductCatalog に提供したらどうなるでしょうか?
メイン クラス ECommerceMainApplication は、ファクトリ メソッド ProductFactory.create() を使用して ProductRepository のインスタンスを作成し、このインスタンスは ProductRepositroy クラスのコンストラクターの引数として渡されます。
public class ECommerceMainApplication { public static void main(String agrs[]) { ProductRepository productRepository = ProductFactory.create(); ProductCatalog productCatalog = new ProductCatalog(productRepository); productCatalog.listAllProducts(); } }
それに応じて ProductCatalog クラスを更新した後
import java.util.List; public class ProductCatalog { private ProductRepository productRepository; public ProductCatalog(ProductRepository productRepository) { this.productRepository = productRepository; } public void listAllProducts(){ List<String> allProductsNames = productRepository.getAllProductNames(); //Display all products names allProductsNames.forEach(product-> System.out.println(product)); } }
これで、ProductCatalog はいつでもどこでも自由に SQLProductRepository オブジェクトを使用できるようになりました。 SQLProductRepository オブジェクトを独自に作成することを心配する必要はなくなりました。
言い換えれば、ProductCatalog が依存関係のインスタンス化を心配するのではなく、依存関係を ProductCatalog に注入しています。
これは依存性注入
制御の反転 - IOC
DIP (Dependency Inversion Principle) の一部ではありませんが、密接に関連しています
上記と同じコードでこれを理解してみましょう
クラス ProductCatalog には、ProductRepository オブジェクトを受け取るコンストラクターがありました。
ProductCatalog を呼び出すクラスは、ProductRepository のオブジェクトを提供または注入します。この場合、それは ECommerceMainApplication です。
注: 注入は ProductCatalog クラスの外部で発生しますが、注入はプログラムのメイン フロー中に発生します。つまり、注入はプログラム実行のメインスレッドで行われます。
すべてのインジェクションを別のスレッドまたは別のコンテキストで完全に実行して、メインの制御フローをインジェクションから完全に分離したい場合はどうなるでしょうか?
これは、Spring(Java の場合) のようなフレームワークを使用して実現できます。
Spring はプログラムのメインフローとは異なる独自のコンテキストを実行します
Spring は、クラスに必要な依存関係の注入を処理します。したがって、クラスのオブジェクトをインスタンス化したい場合は、コード内で直接行うのではなく、Spring にクラスのオブジェクトを提供するよう依頼します。
Spring フレームワークは、オブジェクトのインスタンス化に必要なすべての依存関係を調べてから、すべての依存関係を注入し、オブジェクトをインスタンス化し、それをメインの制御フローに返します。
したがって、依存関係注入の制御は Spring フレームワークに完全に委任され、メール制御フローでは発生しません。
この概念は制御の反転 (IOC) と呼ばれ、スプリングは制御の反転コンテナ、または単に IOC コンテナ
以上が依存関係逆転の原則の詳細内容です。詳細については、PHP 中国語 Web サイトの他の関連記事を参照してください。

ホットAIツール

Undresser.AI Undress
リアルなヌード写真を作成する AI 搭載アプリ

AI Clothes Remover
写真から衣服を削除するオンライン AI ツール。

Undress AI Tool
脱衣画像を無料で

Clothoff.io
AI衣類リムーバー

Video Face Swap
完全無料の AI 顔交換ツールを使用して、あらゆるビデオの顔を簡単に交換できます。

人気の記事

ホットツール

メモ帳++7.3.1
使いやすく無料のコードエディター

SublimeText3 中国語版
中国語版、とても使いやすい

ゼンドスタジオ 13.0.1
強力な PHP 統合開発環境

ドリームウィーバー CS6
ビジュアル Web 開発ツール

SublimeText3 Mac版
神レベルのコード編集ソフト(SublimeText3)

ホットトピック











一部のアプリケーションが適切に機能しないようにする会社のセキュリティソフトウェアのトラブルシューティングとソリューション。多くの企業は、内部ネットワークセキュリティを確保するためにセキュリティソフトウェアを展開します。 ...

多くのアプリケーションシナリオでソートを実装するために名前を数値に変換するソリューションでは、ユーザーはグループ、特に1つでソートする必要がある場合があります...

システムドッキングでのフィールドマッピング処理は、システムドッキングを実行する際に難しい問題に遭遇することがよくあります。システムのインターフェイスフィールドを効果的にマッピングする方法A ...

intellijideaultimatiateバージョンを使用してスプリングを開始します...

データベース操作にMyBatis-Plusまたはその他のORMフレームワークを使用する場合、エンティティクラスの属性名に基づいてクエリ条件を構築する必要があることがよくあります。あなたが毎回手動で...

Javaオブジェクトと配列の変換:リスクの詳細な議論と鋳造タイプ変換の正しい方法多くのJava初心者は、オブジェクトのアレイへの変換に遭遇します...

eコマースプラットフォーム上のSKUおよびSPUテーブルの設計の詳細な説明この記事では、eコマースプラットフォームでのSKUとSPUのデータベース設計の問題、特にユーザー定義の販売を扱う方法について説明します。

Redisキャッシュソリューションは、製品ランキングリストの要件をどのように実現しますか?開発プロセス中に、多くの場合、ランキングの要件に対処する必要があります。
