# 依存関係逆転の原則
DIP (Dependency Inversion Principle)
上位のモジュールは下位のモジュールに依存してはならない。どちらのモジュールも抽象に依存すべきである
モジュール間の依存関係をなくし、間にインターフェースを挟みましょう。上位モジュールが下位モジュールに依存してしまうと、下位モジュールの変更が上位モジュールに伝搬してしまいます。
また、そのインターフェースは上位モジュール側に持ちましょう。詳細を扱う下位モジュールよりも上位モジュールのほうが一般的に安定しているためです。
NOTE
下位モジュールが上位モジュールのインターフェースを実装する
# 依存性の注入(DI: Dependency Injection)
上位モジュールで使用する下位モジュールのインスタンスは依存性の注入を行います。専用のライブラリもいくつかありますが、下のような方法もあります。
const engine: IEngine = new Engine();
const app: App = new App(engine);
app.start();
App
が上位モジュール、Engine
が下位モジュール、IEngine
が間のインターフェースです。ポイントは App
から Engine
への依存がなく、App
と Engine
がどちらも IEngine
に依存していることです。
NOTE
依存性の注入によって下位モジュールへの依存をなくす
# 注意
DIPを適用すべきでないケースがいくつかあります。
- 下位モジュールが安定している場合
依存関係を逆転させる目的は、下位モジュールの変更を上位モジュールに伝搬させないためです。下位モジュールに変更が発生しないのであれば適用する必要はありません。
- 下位モジュールが汎用的なモジュールの場合
下位モジュールが複数のモジュールから利用される場合、特定の上位モジュールに定義したインターフェースに依存することはできません。その場合は一度下位モジュールで定義したインターフェースを変更しないようにしましょう。