Bridgeパターン

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

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

````java
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役に対して機能を追加した役。

````java
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役のインターフェースを実装するためのメソッドを規定する役。

````java
package bridge;

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

###ConcreteImplementor(具体的な実装者)の役
具体的にImplementor役のインターフェースを実装する役。

````java
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("+");
	}
}
````

###呼び出し元

````java
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](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/197834/1bf48669-d06a-b772-9eef-02e3a2dcbebf.png)

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

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

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

###だんだん回数を増やして表示するという「機能」を表すクラス
````java
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;
		}
	}
}
````

###文字で表示するという「実装」を表すクラス
````java
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);
	}
}
````

###呼び出し元

````java
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](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/197834/8f8bfb05-0f92-8b49-a8d2-f00ce73f27ca.png)

https://github.com/aki0207/bridge

こちらを参考にさせていただきました。
<a href="https://www.amazon.co.jp/%E5%A2%97%E8%A3%9C%E6%94%B9%E8%A8%82%E7%89%88Java%E8%A8%80%E8%AA%9E%E3%81%A7%E5%AD%A6%E3%81%B6%E3%83%87%E3%82%B6%E3%82%A4%E3%83%B3%E3%83%91%E3%82%BF%E3%83%BC%E3%83%B3%E5%85%A5%E9%96%80-%E7%B5%90%E5%9F%8E-%E6%B5%A9/dp/4797327030/ref=sr_1_1?ie=UTF8&qid=1454743284&sr=8-1&keywords=java%E8%A8%80%E8%AA%9E%E3%81%A7%E5%AD%A6%E3%81%B6%E3%83%87%E3%82%B6%E3%82%A4%E3%83%B3%E3%83%91%E3%82%BF%E3%83%BC%E3%83%B3%E5%85%A5%E9%96%80">増補改訂版Java言語で学ぶデザインパターン入門</a>