ブログトップ 記事一覧 ログイン 無料ブログ開設

Strategic Choice

2009-01-28

[]依存関係逆転の原則(DIP)

依存関係逆転の原則(DIP:the Dependency Inversion Principle)

上位のモジュールは下位のモジュールに依存してはならない。どちらのモジュールも「抽象」に依存すべきである。

「抽象」は実装の詳細に依存してはならない。実装の詳細が「抽象」に依存すべきである。

どういうこと?

  • 手続き型は「方針」が実装の「詳細」に依存する構造になってしまう。
  • 方針が詳細の変更に影響されてしまう好ましくない構造。
  • OOプログラミングでは「方針」「詳細」とも抽象に依存させることで、悪しき依存関係を逆転できる。

なんで?

  • アプリケーションの方針を決めていて、他に対して影響を与えるモジュールは「上位」。
  • 上位が下位に依存してしまうと、上位が(地位が上であるにもかかわらず)下位の影響を受けてしまう。
  • 手続き型でよく見られた悪い依存関係。
  • 筋的にはアプリケーションの存在理由である上位が下位に対して影響力を持つべき。
    • この場合の上位、下位は必ずしも継承のことではない。
  • よって、これを「逆転」しなければならない。
  • それにより抽象と実装の詳細は完全に切り離され、コードの保守がずっと楽になる。

この原則はフレームワーク設計の核心である。

たとえば?

認識の甘いレイヤ構造。

f:id:asakichy:20090128153200p:image

  • 影響が伝達しやすい依存関係になっている。
  • 最上位から最下位まで連動してしまってる。

どうすれば?

上述をより適切な階層モデルに修正。

f:id:asakichy:20090128153201p:image

  • 上位レイヤが下位のレイヤに依存することがなくなっている。
  • 「逆に」サービスを受けるために上位のレイヤが宣言したインターフェイスに依存しているのは下位のレイヤである。
  • そして、最上位から最下位までの連動がなくなったどころか、その直下にすら連動しなくなっている。

また、依存性だけでなく、「所有権」も逆転している。

  • インターフェイスはライブラリが所有するものと思いがち。
  • DIPを適用すると、クライアントがそのインターフェイスを所有し、ライブラリのサービスがそのインターフェイスから導かれる。
  • 所有権が逆転したことで、たとえばPolicyはIPolicyServiceを実装しているモジュールであれば何でも再利用できる。
  • インターフェイスはクライアントのものである。

実装レベルで言うと、

  • 具体的なクラスへのポインタやリファレンスを保持するような変数があってはならない。
  • 具体的なクラスから派生するクラスがあってはならない。
  • 基本クラスで実装されているメソッドを上書きしてしまうようなメソッドがあってはならない。

テクニックは?

  • DIコンテナ
    • インターフェイス(抽象)を管理。
    • 実装のインスタンス化を行う。
    • インスタンスをクライアントに渡す。
    • つまり「依存性の注入」を行う役割を担ってくれる。
  • ハリウッドの原則
    • 「連絡してくるなよ。必要なときはこちらから連絡するから」
    • DIP適用後の所有権が逆転した状態。

まとめ

  • DIPを一言で説明すると「抽象に依存せよ」という経験則。
    • プログラムは具体的なクラスに依存してはいけない。
    • プログラム内の関係はすべて、抽象クラスかインターフェースで終結すべきである。

関連

  • DI(Dependency Injection)

スパム対策のためのダミーです。もし見えても何も入力しないでください
ゲスト


画像認証