デザインパターン学習メモ：「Bridge」


## このパターンの目的
GoF本より引用する。

> 抽出されたクラスと実装を分離して、それらを独立に変更できるする。（P.163）

流動的な要素が複数あるときに、それらを別の階層として扱う。（二つの階層の接続はコンポジションを用いる）
そうすることで、それぞれ独立して変更することができ、将来的なクラス数の増大に備えることができる。

## 実装例
『オブジェク指向のこころ』(P.163)を参考に作成

### 「抽出されたクラス」の階層

```java:Shape.java
// Abstractionの役割
public abstract class Shape {
	protected Drawing drawing;  // 実装を表すクラスのインスタンス
	
	public Shape(Drawing drawing) {
		this.drawing = drawing;
	}
	
	abstract void draw();
	
	protected void drawingLine(double x1, double y1, double x2, double y2) {
		drawing.drawLine(x1, y1, x2, y2);
	}
	
	void drawCircle(double x, double y, double r) {
		drawing.drawCircle(x, y, r);
	}
}
```

```java:Rectangle.java
// RefinedAbstraction の役割
public class Rectangle extends Shape {
	private double x1, x2, y1, y2;

	public Rectangle(Drawing drawing, double x1, double x2, double y1, double y2) {
		super(drawing);
		this.x1 = x1;
		this.x2 = x2;
		this.y1 = y1;
		this.y2 = y2;
	}

	@Override
	void draw() {
		drawing.drawLine(x1, y1, x2, y1);
		drawing.drawLine(x2, y1, x2, y2);
		drawing.drawLine(x2, y2, x1, y2);
		drawing.drawLine(x1, y2, x1, y1);
	}
}
```

```java:Circle.java
// Abstractionの役割
public class Circle extends Shape {
	private double x, y, r;

	public Circle(Drawing drawing, double x, double y, double r) {
		super(drawing);
		this.x = x;
		this.y = y;
		this.r = r;
	}

	@Override
	void draw() {
		drawing.drawCircle(x, y, r);
	}
}
```

### 「実装」の階層

```java:Drawing.java
// Implementorの役割
public interface Drawing {
	void drawLine(double x1, double y1, double x2, double y2);
	void drawCircle(double x, double y, double r);
}
```

```java:FooSystemDrawing.java
// Concrete Implementorの役割
public class FooSystemDrawing implements Drawing {

	@Override
	public void drawLine(double x1, double y1, double x2, double y2) {
		// FooSystemに依存した線分の描画処理
	}

	@Override
	public void drawCircle(double x, double y, double r) {
		// FooSystemに依存した円の描画処理
	}
}
```

```java:BarSystemDrawing.java
// Concrete Implementorの役割
public class BarSystemDrawing implements Drawing{

	@Override
	public void drawLine(double x1, double y1, double x2, double y2) {
		// BarSystemに依存した線分の描画処理
	}

	@Override
	public void drawCircle(double x, double y, double r) {
		// BarSystemに依存した円の描画処理
	}
}
```

## 実装例の解説
Shapeクラスが抽出されたクラスである。クライアントは図形をShapeクラスとして扱う。（ポリモーフィズム）

この図形の描画方法は、各システム（Fooシステム、Barシステム）によって異なるので、その描画方法は「実装の階層」として分離する。
こうすることで、今後bazシステムに対応する必要があったときに、BarSystemDrawingクラスを作ることだけで対応可能になる。

## 各書籍における表現の違い
参考にした書籍で、Bridgeパターンの表現がそれぞれ異なっていて面白かったので紹介する。

### GoF本の原書
> Decouple an abstraction from its implementation

### GoF本の翻訳
> 抽出されたクラスと実装を分離

「抽出」は、「オブジェクト指向分析の結果、クラスとして抽出された」という意味だろうか

### 『Java言語で学ぶ　デザインパターン入門』
> 「機能のクラス階層」と「実装のクラス階層」

「クラス階層」という表現はわかりやすい。「機能」という表現がやや気になる。（あまりピンとこない）

### 『オブジェクト指向のこころ』
> 抽象的側面と実装

翻訳を読んでいるので、原書がどうなっているのか分からない。
「抽象的側面」はGoF本と同じく"abstraction"となっているのか、違うのか。（違う気がする）

### 『アジャイルソフトウェア開発の奥義』
> 抽象的な部分と具体的な部分に分離

## 参考文献
 * エリック ガンマ、ラルフ ジョンソン、リチャード ヘルム、ジョン プリシディース（1999）『オブジェクト指向における再利用のためのデザインパターン　改訂版』本位田　真一、吉田　和樹 監訳、SBクリエイティブ
 * ロバート・C・マーチン（2004）『アジャイルソフトウェア開発の奥義　第２版　オブジェクト指向開発の神髄と匠の技』瀬谷啓介訳、SBクリエイティブ
 * アラン・シャロウェイ、ジェームズ・R・トロット（2014）『デザインパターンととともに学ぶ　オブジェクト指向のこころ』村上雅章訳、丸善出版
 * 結城浩（2004）『Java言語で学ぶ　デザインパターン入門』SBクリエイティブ