LoginSignup
0
1

More than 3 years have passed since last update.

Bridgeパターン

Last updated at Posted at 2020-09-08

Bridgeパターンとは

「機能のクラス階層」と「実装のクラス階層」の橋渡しを行う。
wikipediaには、「橋渡し」のクラスを用意することによって、クラスを複数の方向に拡張させることを目的とすると書かれている。

Abstraction(抽象化)の役

「機能のクラス階層」の最上位のクラス。
Implementor役のメソッドを使って基本的な機能だけが記述されているクラス。
このクラスはImplementor役を保持する。

package bridge;

public class Display {
    private DisplayImpl impl;

    public Display(DisplayImpl impl) {
        this.impl = impl;
    }

    public void open() {
        impl.rawOpen();
    }

    public void print() {
        impl.rawPrint();
    }

    public void close() {
        impl.rawClose();
    }

    public final void display() {
        open();
        print();
        close();
    }
}

RefinedAbstraction(改善した抽象化)の役

Abstraction役に対して機能を追加した役。

package bridge;

public class CountDisplay extends Display {
    public CountDisplay(DisplayImpl impl) {
        super(impl);
    }

    public void multiDisplay(int times) {
        open();
        for (int i = 0; i < times; i++) {
            print();
        }
        close();
    }
}

Implementor(実装者)の役

「実装のクラス階層」の最上位のクラス。
Abstraction役のインターフェースを実装するためのメソッドを規定する役。

package bridge;

public abstract class DisplayImpl {
    public abstract void rawOpen();
    public abstract void rawPrint();
    public abstract void rawClose();
}

ConcreteImplementor(具体的な実装者)の役

具体的にImplementor役のインターフェースを実装する役。

package bridge;

public class StringDisplayImpl extends DisplayImpl {
    private String string;
    private int width;

    public StringDisplayImpl(String string) {
        this.string = string;
        this.width = string.getBytes().length;
    }

    public void rawOpen() {
        printLine();
    }

    public void rawPrint() {
        System.out.println("|" + string + "|");
    }

    public void rawClose() {
        printLine();
    }

    public void printLine() {
        System.out.print("+");
        for (int i = 0; i < width; i++) {
            System.out.print("-");
        }
        System.out.println("+");
    }
}

呼び出し元

package bridge;

public class Main {
    public static void main(String[] args) {
        Display d1 = new Display(new StringDisplayImpl("Hello Japan"));
        Display d2 = new CountDisplay(new StringDisplayImpl("Hello World"));
        CountDisplay d3 = new CountDisplay(new StringDisplayImpl("Hello Universe"));
        d1.display();
        d2.display();
        d3.display();
        d3.multiDisplay(5);
    }
}

実行結果

スクリーンショット 2020-09-07 18.58.23.png

以下のような模様を表示するクラスを追加する。
<>
<*>
<**>
<***>

これらは初めの文字→飾り文字が複数回→終わりの文字と改行を1行として、それが複数回繰り返される。

上のような動作をするクラスを追加する場合は、「機能」を表すクラスと「実装」を表すクラスに分離する。

だんだん回数を増やして表示するという「機能」を表すクラス

package bridge;

public class IncreaseDisplay extends CountDisplay {
    // 増加数
    private int step;

    public IncreaseDisplay(DisplayImpl impl, int step) {
        super(impl);
        this.step = step;
    }

    public void increaseDisplay(int level) {
        int count = 0;
        for (int i = 0; i < level; i++) {
            multiDisplay(count);
            count += step;
        }
    }
}

文字で表示するという「実装」を表すクラス

package bridge;

public class CharDisplayImpl extends DisplayImpl {
    private String firstLetter;
    private String decoration;
    private String lastLetter;

    public CharDisplayImpl(String firstLetter, String decoration, String lastLetter) {
        this.firstLetter = firstLetter;
        this.decoration = decoration;
        this.lastLetter = lastLetter;
    }

    @Override
    public void rawOpen() {
        System.out.print(firstLetter);
    }

    @Override
    public void rawPrint() {
        System.out.print(decoration);
    }

    @Override
    public void rawClose() {
        System.out.println(lastLetter);
    }
}

呼び出し元

package bridge;

public class Main {
    public static void main(String[] args) {
        Display d1 = new Display(new StringDisplayImpl("Hello Japan"));
        Display d2 = new CountDisplay(new StringDisplayImpl("Hello World"));
        CountDisplay d3 = new CountDisplay(new StringDisplayImpl("Hello Universe"));
        IncreaseDisplay d4 = new IncreaseDisplay(new CharDisplayImpl("<", "*", ">"), 2);
        d1.display();
        d2.display();
        d3.display();
        d3.multiDisplay(5);
        d4.increaseDisplay(3);
    }
}

実行結果

スクリーンショット 2020-09-08 11.38.58.png

こちらを参考にさせていただきました。
増補改訂版Java言語で学ぶデザインパターン入門

0
1
0

Register as a new user and use Qiita more conveniently

  1. You get articles that match your needs
  2. You can efficiently read back useful information
  3. You can use dark theme
What you can do with signing up
0
1