オブジェクト指向設計


Dependency Inversion Principle (DIP) - OO設計のDIP依存逆転原則

2008/06/09 20:53Update
TAGS: DIP | 依存逆転原則 | OOD | オブジェクト指向設計

上位モジュールは下位モジュールに依存してはならない。両者は抽象に依存すべきである。抽象は詳細(抽象の実装クラス)に依存してはならない。詳細は抽象に依存すべきである。

Robert C. Martin氏による有名なオブジェクト指向設計(OOD)の原則“Principles of OOD”があります。

本文は“Principles of OOD”の依存関係の逆転原則:Dependency Inversion Principle (DIP)について学びます。

DIP依存逆転原則はクラス同士の結合度をいかに減らすか、またはどちらに依存すべきかを判定する原則です。

概要


A. High level modules should not depend upon low level modules. Both should depend upon abstractions.
上位モジュールは下位モジュールに依存してはならない。両者は抽象に依存すべきである。
B. Abstractions should not depend upon details. Details should depend upon abstractions.
抽象は詳細(抽象の実装クラス)に依存してはならない。詳細は抽象に依存すべきである。

依存関係:
JavaやCなどのプログラミングの依存関係とは、モジュール(関数、メソッド)間の呼び出し関係です。モジュールAはモジュールBを呼出していることは、AはBに依存していることです。

上位モジュール:簡単に言うと、上層にいるモジュール、または呼ぶ側のモジュールとのことです。上位モジュールはより大きな枠、概念、サービスなどを提供します。
下位モジュール:下層にいるモジュール、または呼出される側のモジュールとのことです。下位モジュールはより詳細(細かい)、具体的な処理を提供します。
例:
//データ転送
transferData() {
    //①キーボードから入力データの取得
    data = getKeybordInput();
    //②データをプリンタに転送
    transfer2Print(data);
}

上の例では、transferDataというモジュールを上位モジュールと呼び、getKeybordInputとtransfer2Printを下位モジュールと呼びます。

抽象:一般的に、オブジェクト指向の抽象とは抽象クラスまたはインタフェースとのことです。
詳細:抽象クラスやインタフェースの実装クラスです。

依存(関係)逆転:上記の例では、transferDataはgetKeybordInputとtransfer2Printを依存します、つまり、上位モジュールは下位モジュールを依存してしまいます。
DIP依存逆転原則は上位モジュールは下位モジュールを依存しないようにします。これは「逆転」という名前の由来です。

では、なぜ、「上位モジュールは下位モジュールに依存してはならない」のでしょうか?

問題


Robert C. Martin氏はいくつかの“Bad Design”(よくないデザイン)を提起しました。
1. It is hard to change because every change affects too many other parts of the system.(Rigidity)
変更しづらい。システムのほかの部分も変更の影響を受けてしまい、変更しづらくなります。

2. When you make a change, unexpected parts of the system break. (Fragility)
壊れやすい。一箇所を修正して、システムの予期せぬ部分が動作しなくなってしまいます。

3. It is hard to reuse in another application because it cannot be disentangled from the current application. (Immobility)
再利用性低い。アプリケーションから分離することは難しいため、モジュールの再利用性は非常に低い。

その原因は上位モジュールが下位モジュールに依存しすぎると考えられ、下位モジュールの変更によって上位モジュールも変更しなければならなかったからです。

問題の解決


“Bad Design”(よくないデザイン)を解消するために、Robert C. MartinはDependency Inversion Principle (DIP) 原則を提唱します。

High Level Classes(上位モジュール) --> Abstraction Layer(抽象レイヤー) --> Low Level Classes(下位モジュール)

上位モジュールと下位モジュールの間でAbstraction Layer(抽象レイヤー)を追加することで、“Bad Design”を解消します。
Abstraction Layer(抽象レイヤー)は下位モジュールのインタフェースであり、下位モジュールはそれを実装します。また、上位モジュールはAbstraction Layer(抽象レイヤー)を呼ぶようにし、下位モジュールに依存しなくなります。

これで、上位モジュールは下位の実装モジュールの変更影響を受けずに済むことができます。

参考資料


Dependency Inversion Principle (DIP)「PDF。英語」

有关作者
Syboos.jp編集長AJavaやオープンソース情報の執筆、Webサイトの開発や運営全般の業務に携わる。

Sponsored Link


Comments