Dependency Inversion Principle (DIP) - OO設計のDIP依存逆転原則
2008/06/09 20:53Update
上位モジュールは下位モジュールに依存してはならない。両者は抽象に依存すべきである。抽象は詳細(抽象の実装クラス)に依存してはならない。詳細は抽象に依存すべきである。
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。英語」
本文は“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。英語」
Sponsored Link
- Relative Articles
- Single Responsibility Principle (SRP) - OO設計のSRP単一責任原則 - (2008/06/08 01:34)
- Interface Segregation Principle (ISP) - OO設計のISPインターフェイス分離原則 - (2008/06/08 22:18)
- Liskov Substitution Principle (LSP) - OO設計のLSP リスコフ置換原則 - (2008/06/09 13:18)
- The Stable Dependencies Principle (SDP) - OO設計のSDP安定依存原則 - (2008/06/09 16:53)
- The Acyclic Dependencies Principle (ADP) - OO設計のADP非循環依存原則 - (2008/06/09 17:33)
- The Stable Abstractions Principle (SAP) - OO設計のSAP安定度・抽象度等価原則 - (2008/06/09 17:48)
- The Common Closure Principle (CCP) - OO設計のCCP閉鎖性共通原則 - (2008/06/09 18:04)
- Release Reuse Equivalency Principle (REP) - OO設計のREP再利用・リリース等価原則 - (2008/06/09 18:15)
- The Common Reuse Principle (CRP) - OO設計のCRP全再利用原則 - (2008/06/09 18:24)
- オブジェクト指向設計の原則 概要 - (2008/07/21 22:03)