Bridge

パターンの目的

抽出されたクラスと実装を分離して、それらを独立に変更できるようにする。

GoF パターンのクラス図

structure-08-05:bridge

MixJuice 版 Bridge (改善)

解決される GoF パターンの問題点

拡張性の問題点
クラス Abstraction およびクラス Implementor で、十分なオペレーションをあらかじめ定義しておく必要がある。オペレーションをあとから追加するためには、ソースコードの修正が必要になる。例えば GoF 本の動機の章の例でいえば、 DrawText と DrawLine というオペレーションに加えて、あとから DrawImage というオペレーションが必要になることは容易に想像できる。(この問題点は GoF 本では指摘されていない。頻繁に起こり得る問題ではないだろうか?)

対策

クラス Abstraction へのメソッド追加および抽象クラス Implementor へのアブストラクトメソッド追加により、あとからオペレーションを追加できる。

結果

あらかじめ予想されていなかったオペレーションを追加することが可能になる。すべての ConcreteImplementor クラスに、追加されたオペレーションを実装する補完モジュールが必要になる。

構造

xxx

MixJuice 版 Bridge (別解)

解決される GoF パターンの問題点

型安全性の問題点
クラス数増加の問題点

対策

Bridge パターンが目的とする状況は Abstraction と Implementation を独立して選択できる場合である。

機能と実装の拡張
Implementation
X Window SystemPresentation Manager
Abstractionicon
transient

この独立性を実現するために、Bridge パターンでは Abstraction と Implementation のふたつのクラス階層を使う。しかし、MixJuice では、Implementation の拡張を差分によって実現することにより、ひとつのクラス階層で同様な拡張性を実現できる。

結果

ひとつのバイナリでひとつの Implementation しか使用しないのであれば、 MixJuice ではクラス階層をひとつで済ますことができる。

構造

structure-08-09:bridge

module original {
  define class Abstraction {
    define void operation() {
      ... implementationOperation1(); ...
    }

    define abstract void implementationOperation1();
    define abstract void implementationOperation2();
  }

  define class RefinedAbstractionA extends Abstraction {...}
  define class RefinedAbstractionB extends Abstraction {...}
}

module implementation1 extends original {
  class Abstraction {
    void implementationOperation1() {...}
    void implementationOperation2() {...}
  }
}

module implementation2 extends original {
  class Abstraction {
    void implementationOperation1() {...}
    void implementationOperation2() {...}
  }
}

サンプルコード

structure-08-09:bridge_sample

module window {
  define class Window {
    define void drawRect() {
      drawLine();
      drawLine();
      drawLine();
      drawLine();
    }

    define abstract void drawText();
    define abstract void drawLine();
  }

  define class IconWindow extends Window {...}
  define class TransientWindow extends Window {...}
}

module window.implementation.x extends window {
  class Window {
    void drawText() {... XDrawString(); ...}
    void drawLine() {... XDrawLine(); ...}
  }
}

module window.implementation.pm extends window {
  class Window {
    void drawText() {...}
    void drawLine() {...}
  }
}

関連するパターン


MixJuice によるデザインパターン改善カタログ


田中 哲 <akr@m17n.org>, 一杉 裕志 <y-ichisugi@aist.go.jp>