# 依存関係逆転の原則

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 への依存がなく、AppEngine がどちらも IEngine に依存していることです。

NOTE

✏️ 依存性の注入によって下位モジュールへの依存をなくす

# 注意

DIPを適用すべきでないケースがいくつかあります。

  • 下位モジュールが安定している場合

依存関係を逆転させる目的は、下位モジュールの変更を上位モジュールに伝搬させないためです。下位モジュールに変更が発生しないのであれば適用する必要はありません。

  • 下位モジュールが汎用的なモジュールの場合

下位モジュールが複数のモジュールから利用される場合、特定の上位モジュールに定義したインターフェースに依存することはできません。その場合は一度下位モジュールで定義したインターフェースを変更しないようにしましょう。