安定依存の原則(SDP)を初心者向けに解説

設計

安定依存の原則(SDP)とは?

安定依存の原則(SDP: Stable Dependencies Principle)は、ソフトウェア設計における重要な原則の一つで、「安定したコンポーネントにのみ依存するべき」という考え方です。

簡単に言うと、「変更されにくい(=安定した)コンポーネントに依存すれば、システム全体が安定する」というルールです。

安定度の指標

安定度(Stability)は、次の2つの指標を用いて評価します

  1. Fan-in(外部から依存される数)
    • どれだけのモジュールがそのモジュールに依存しているかを表します。
    • 値が高いほど、そのモジュールは「安定している」とみなされます。
  2. 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...");
    }
}
問題点
  1. 頻繁な変更の影響を受ける
    • UserInterface は頻繁に変更される可能性が高い(例:UIデザインや表示内容の変更)。
    • その結果、OrderManager も影響を受け、修正が必要になります。
  2. 保守性が低下
    • OrderManager は、UIの実装に強く依存しているため、UIの仕様変更に合わせて修正しなければならなくなります。
  3. 柔軟性がない
    • 例えば、異なる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");
    }
}
なぜこれが良い設計なのか?
  1. OrderManagerは「安定した抽象(Display)」に依存
    • OrderManager は、Display というインターフェースに依存しており、具体的な実装(DesktopUIMobileUI)には依存していません。
    • これにより、UIの実装が変更されても、Display のインターフェースさえ変わらなければ OrderManager には影響がありません。
  2. 柔軟性が向上
    • 新しいUI(たとえばWebUI)を追加したい場合、OrderManager を変更することなく、新しいUIクラスを Display インターフェースとして実装すれば良いだけです。
  3. 変更の影響範囲が限定される
    • UIの具体的な変更が、システム全体に波及するリスクが減ります。

全てのコンポーネントに安定度を求める必要はない理由

柔軟性が必要な部分もある

  • システムの中には、頻繁に変更される部分(例えばUIやビジネスロジック)が存在します。
  • これらの部分に安定性を求めると、変更が困難になり、システム全体の柔軟性が損なわれます。

抽象と具体のバランスが重要

  • 安定すべき部分: 基盤となる部分や多くのモジュールから依存される部分(例:インターフェースやデータベースアクセス層)。
  • 柔軟性を重視すべき部分: 頻繁に変わる機能(例:UIや外部サービスとの連携)。

まとめ

  • 安定依存の原則(SDP)は、安定したコンポーネントに依存することで、システム全体の保守性と安定性を向上させる原則です。
  • 安定度の指標を用いてモジュールの状態を客観的に評価し、依存関係を適切に設計することが重要です。
  • 全てのモジュールに安定性を求める必要はなく、柔軟性が求められる部分も存在します。

コメント

タイトルとURLをコピーしました