Bridge パターン

「Bridge」という英単語は、「橋」を意味します。

このパターンは、以下で説明している「1, 2」の架け橋を提供するパターンです。


まず、継承の目的について考えてみます。継承の目的としては、主に次の2つが考えられます。

  1. 「機能追加」(スーパークラスが持っていない機能をサブクラスで追加)を目的としたもの
  2. 「機能実装」(スーパークラスで定義したインタフェースをサブクラスで実装)を目的としたもの

次は、この「1, 2」の継承関係が発達していくと、どういう問題が発生するかについて説明したいと思います。

下図を見てください。


抽象クラスAと、Aを継承し抽象メソッドを実装したクラスA1・A2の下図の関係があるとします。

サンプルイメージ1

上図状態のクラス関係に、抽象クラスAへの機能追加のため、クラスABを追加したとします。(下図参照)

この場合、クラスABからは、クラスA1・A2の実装メソッドをそのまま使用することができません。(Aを継承しているので、抽象メソッドのインタフェースは存在するが、クラスABの実装がない)

サンプルイメージ2

そこで、下図の様にA1・A2と同じ実装内容のクラスA1'・A2'を、クラスABのサブクラスとして追加しました。

これでひとまずクラスABからも、クラスA1'・A2'の実装メソッドを使用できるようになりました。


が、またまた今度は、クラスABに機能を追加しなくてはいけなくなったので、クラスABCを追加しました。

そのため、クラスA1''・A2''を追加しました・・・・。

サンプルイメージ3

この様に、クラスA(AB)に機能を追加しようと思うと、そのサブクラス(機能実装)まで追加しなければなりません。つまり、機能を追加する度に、その実装クラス(A1、A2)まで追加していかなければならなくなります。(機能追加クラス(1.の継承関係)数 × 実装クラス(2.の継承関係)数分のクラスを作成しなければならなくなる)


この問題を解消してくれるのが「Bridge」パターンです。

下図を見てください。

サンプルイメージ4

この様に機能実装関係のクラスを、クラスAに保持させる(架け橋を作る)事により、機能追加しても実装関係のクラス階層には影響せず、また逆に、実装クラスを追加しても機能のクラス階層に影響しない構造にすることができました。


役割り

1. Abstraction(抽象化)
機能追加の継承関係の最上位クラスです。「Implementor」を内部に保持し、「Implementor」のメソッドを使用した基本的な機能を提供します。
2. RefinedAbstraction(改善した抽象化)
「Abstraction」を機能追加したクラスです。「Abstraction」とは、機能追加の継承関係にあります。
3. Implementor(実装者)
機能実装の継承関係の最上位クラスです。「Abstraction」が使用するメソッドのインタフェースを定義します。
4. ConcreteImplementor(具体的な実装者)
「Implementor」が定めたインタフェースを実装します。
5. Client(利用者)
「Bridge」パターンを適用したクラスを利用し処理します。

▲PageTop

クラス図

Bridgeパターンのクラス図

Bridgeパターン クラス図

▲PageTop

サンプル

ソースコード

1. Abstraction.java

public class Abstraction {
    private Implementor impl;
    public Abstraction(Implementor impl) {
        this.impl = impl;
    }
    public void abstractionMethod() {
        impl.implMethod();
    }
}

2. RefinedAbstraction.java

public class RefinedAbstraction extends Abstraction {
    public RefinedAbstraction(Implementor impl) {
        super(impl);
    }
    public void refinedMethod() {
        System.out.println("追加機能");
    }
}

3. Implementor.java

public abstract class Implementor {
    public abstract void implMethod();
}

4. ConcreteImplementor.java

public class ConcreteImplementor extends Implementor {
    public void implMethod() {
        System.out.println("実装機能");
    }
}

5. Client.java

public class Client {
    public static void main(String[] args) {
        Abstraction abstraction = new Abstraction(new ConcreteImplementor());
        RefinedAbstraction refinedAbstraction = new RefinedAbstraction(new ConcreteImplementor());
        abstraction.abstractionMethod();
        refinedAbstraction.abstractionMethod();
        refinedAbstraction.refinedMethod();
    }
}

実行結果

C:\sample\desin_pattern\bridge>javac Client.java [Enter]

C:\sample\desin_pattern\bridge>java Client [Enter]
実装機能
実装機能
追加機能
        

▲PageTop