📢 この記事は gemini-2.5-flash によって翻訳されました
Bridgeパターン オブジェクト構造パターン
意図
抽象部分とその実装部分を分離して、それぞれが独立して変化できるようにするんだ。
構造

構成要素はこれだ:
- Abstractionは抽象クラスのインターフェースを定義して、Implementor型のオブジェクトへのポインタを保持するんだ。
- RefinedAbstractionはAbstractionが定義したインターフェースを拡張する役割だよ。
- Implementorは実装クラスのインターフェースを定義するんだけど、これはAbstractionのインターフェースと完全に一致する必要はないんだ。実際、この2つのインターフェースは全く異なっていても大丈夫。一般的に、Implementorのインターフェースは基本的な操作だけを提供するけど、Abstractionはそれらの基本操作を基にした、より高レベルな操作を定義するって感じだね。
- ConcreteImplementorはImplementorインターフェースを実装して、その具体的な実装を定義するんだ。
適用できる場面
Bridgeパターンはこんな時に便利だよ:
- 抽象とその実装部分の間に固定的な結びつきを持たせたくない時。例えば、プログラムの実行時に実装部分を選択したり、切り替えたりしたい場合なんかがあるね。
- クラスの抽象部分と実装部分の両方を、サブクラスを生成することで拡張できるようにしたい時。Bridgeパターンを使うと、開発者は異なる抽象インターフェースと実装部分を組み合わせて、それぞれを個別に拡張できるようになるんだ。
- 抽象部分の実装を変更しても、クライアントに影響を与えたくない時、つまりクライアントのコードを再コンパイルする必要がないようにしたい時だね。
- (C++の場合) 抽象部分の実装をクライアントから完全に隠したい時。
- 多くのクラスを生成する必要があるクラス階層がある時。
- 複数のオブジェクト間で実装を共有したい時(参照カウントを使うこともありえるね)、でもクライアントにはその事実を知られたくない時。
例
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
| public class main {
public static void main(String[] args) {
Product ProductA1 = new ProductA();
Product ProductA2 = new ProductA();
Color red = new Red();
ProductA1.setName("P-A1");
ProductA1.setColor(red);
ProductA1.Operation;
Color blue = new Blue();
ProductA1.setName("P-A2");
ProductA1.setColor(blue);
ProductA1.Operation;
}
}
abstract class Product{
private String name;
protected Color color;
public void setName(String name){
this.name = name;
}
public String getName(){
return this.name;
}
public setColor(Color color){
this.color = color;
}
public abstract void Operation();
}
class ProductA extends Product{
@Override
public void Operation(){
color.OperationImp(this.getName());
}
}
class Color{
public void OperationImp(String name);
}
class Red extends Color{
@Override
public void OperationImp(String name){
System.out.println(name + ": red")
}
}
class Blue extends Color{
@Override
public void OperationImp(String name){
System.out.println(name + ": blue")
}
}
|