安定依存の原則(SDP)とは?
安定依存の原則(SDP: Stable Dependencies Principle)は、ソフトウェア設計における重要な原則の一つで、「安定したコンポーネントにのみ依存するべき」という考え方です。
簡単に言うと、「変更されにくい(=安定した)コンポーネントに依存すれば、システム全体が安定する」というルールです。
安定度の指標
安定度(Stability)は、次の2つの指標を用いて評価します
- Fan-in(外部から依存される数)
- どれだけのモジュールがそのモジュールに依存しているかを表します。
- 値が高いほど、そのモジュールは「安定している」とみなされます。
- Fan-out(依存している数)
- そのモジュールがどれだけのモジュールに依存しているかを表します。
- 値が低いほど、そのモジュールは「安定している」とみなされます。
安定度の計算式
Plaintext
安定度(I) = Fan-out / (Fan-in + Fan-out)
- I = 0:完全に安定(依存されるだけで、他には依存しない)。
- I = 1:完全に不安定(他に依存するだけで、依存されない)。
具体的な例
NGな例:不安定なモジュールに依存している場合
以下の例では、OrderManager クラスが直接 UserInterface クラスに依存しています。
Java
// 不安定なモジュール(UIの変更は頻繁に発生する可能性がある)
class UserInterface {
public void display() {
System.out.println("Displaying UI");
}
}
// OrderManagerが直接UIに依存している
class OrderManager {
private UserInterface ui;
public OrderManager(UserInterface ui) {
this.ui = ui;
}
public void processOrder() {
ui.display(); // UIのメソッドを直接呼び出す
System.out.println("Processing order...");
}
}
問題点
- 頻繁な変更の影響を受ける
- UserInterface は頻繁に変更される可能性が高い(例:UIデザインや表示内容の変更)。
- その結果、OrderManager も影響を受け、修正が必要になります。
- 保守性が低下
- OrderManager は、UIの実装に強く依存しているため、UIの仕様変更に合わせて修正しなければならなくなります。
- 柔軟性がない
- 例えば、異なるUI(CLI、モバイルUI、WebUI)を使用したい場合、OrderManager を改修する必要があります。
OKな例:安定したモジュールに依存
以下のように、抽象モジュール(インターフェース) を導入することで、依存関係を「不安定な具体的な実装」から「安定した抽象」に切り替えます。
Java
// 安定した抽象モジュール(インターフェース)
interface Display {
void show();
}
// OrderManagerは抽象(Display)に依存する
class OrderManager {
private Display display;
public OrderManager(Display display) {
this.display = display;
}
public void processOrder() {
display.show(); // 抽象モジュールのメソッドを呼び出す
System.out.println("Processing order...");
}
}
// 具体的なUI実装1(デスクトップアプリ用)
class DesktopUI implements Display {
public void show() {
System.out.println("Displaying desktop UI");
}
}
// 具体的なUI実装2(モバイルアプリ用)
class MobileUI implements Display {
public void show() {
System.out.println("Displaying mobile UI");
}
}
なぜこれが良い設計なのか?
- OrderManagerは「安定した抽象(Display)」に依存
- OrderManager は、Display というインターフェースに依存しており、具体的な実装(DesktopUI や MobileUI)には依存していません。
- これにより、UIの実装が変更されても、Display のインターフェースさえ変わらなければ OrderManager には影響がありません。
- 柔軟性が向上
- 新しいUI(たとえばWebUI)を追加したい場合、OrderManager を変更することなく、新しいUIクラスを Display インターフェースとして実装すれば良いだけです。
- 変更の影響範囲が限定される
- UIの具体的な変更が、システム全体に波及するリスクが減ります。
全てのコンポーネントに安定度を求める必要はない理由
柔軟性が必要な部分もある
- システムの中には、頻繁に変更される部分(例えばUIやビジネスロジック)が存在します。
- これらの部分に安定性を求めると、変更が困難になり、システム全体の柔軟性が損なわれます。
抽象と具体のバランスが重要
- 安定すべき部分: 基盤となる部分や多くのモジュールから依存される部分(例:インターフェースやデータベースアクセス層)。
- 柔軟性を重視すべき部分: 頻繁に変わる機能(例:UIや外部サービスとの連携)。
まとめ
- 安定依存の原則(SDP)は、安定したコンポーネントに依存することで、システム全体の保守性と安定性を向上させる原則です。
- 安定度の指標を用いてモジュールの状態を客観的に評価し、依存関係を適切に設計することが重要です。
- 全てのモジュールに安定性を求める必要はなく、柔軟性が求められる部分も存在します。
コメント