Bridge

桥接

将抽象部分与它的实现部分放在两个不同的类层次中,使它们都可以独立地变化。

适用性

  • 你不希望在抽象和它的实现部分之间有一个固定的绑定关系。例如,这种情况可能是因为,在程序运行时刻实现部分应可以选择或者切换。
  • 类的抽象以及它的实现都应该可以通过生成子类的方法加以扩充。这时Bridge使你可以对不同的抽象接口和实现部分进行组合,并分别对它们进行扩充。
  • 对一个抽象的实现部分的修改应对客户不产生影响,即客户的代码不必重新编译。
  • 你想对客户完全隐藏抽象的实现部分。在C++中,类的表示在类接口中是可见的。
  • 想在多个对象间共享实现(可能使用引用计数),但同时要求客户并不知道这一点。

示例情境

遥控器有不同的界面,针对不同电视又有不同的实现。
Bridge Scenario

结构

Bridge Class

Abstraction - 定义抽象类的接口。维护一个指向Implementor类型对象的指针。
RefinedAbstraction - 扩充由Abstraction定义的接口。
Implementor - 定义实现类的接口,该接口不一定要与Abstraction的接口完全一致;事实上这两个接口可以完全不同。一般来讲,Implementor接口仅提供基本操作,而Abstraction则定义了基于这些基本操作的较高层次的操作。
ConcreteImplementor - 实现Implementor接口并定义它的具体实现。

协作:
Abstraction将Client的请求转发给它的Implementor对象。

示例

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
60
61
62
63
64
#include <iostream>
//---------------------------------------------------
class Implementor
{
public:
virtual void operation_imp()
{

std::cout<<"abstract imp."<<std::endl;
}
};
//---------------------------------------------------
class ConcreteImplementorA : public Implementor
{
public:
virtual void operation_imp()
{

std::cout<<"Concrete ImplementationA."<<std::endl;
}
};
//---------------------------------------------------
class ConcreteImplementorB : public Implementor
{
public:
virtual void operation_imp()
{

std::cout<<"Concrete ImplementationB."<<std::endl;
}
};
//---------------------------------------------------
class Abstraction
{
public:
Abstraction(Implementor* imp): m_imp(imp){}
virtual void operation()
{

if (!m_imp) return;
m_imp->operation_imp();
}
protected:
Implementor* m_imp;
};
//---------------------------------------------------
class RefinedAbstraction : public Abstraction
{
public:
RefinedAbstraction(Implementor* imp) : Abstraction(imp){}
virtual void additional_operation()
{

operation();
std::cout<<"I'm additional."<<std::endl;
}
};
//---------------------------------------------------
int main()
{

ConcreteImplementorA a;
ConcreteImplementorB b;
Abstraction interface1(&a);
RefinedAbstraction interface2(&b);
interface1.operation();
interface2.operation();
interface2.additional_operation();
system("Pause");
};

优点

  • 将实现予以解耦,让它和界面之间不再永久绑定。
  • 抽象和实现可以独立扩展,不会影响到对方。
  • 对于“具体的抽象类”所做的改变,不会影响到客户。

用途和缺点

  • 适合使用在需要跨越多个平台的图形和窗口系统上。
  • 当需要用不同的方式改变接口和实现时,你会发现桥接模式很好用。
  • 桥接模式的缺点是增加了复杂度。

相关模式

  • Abstract Factory模式可以用来创建和配置一个特定的Bridge模式。
  • Adapter模式用来帮助无关的类协同工作,它通常在系统设计完成后才会被使用。然而,Bridge模式则是在系统开始时就被使用,它使得抽象接口和实现部分可以独立进行改变。

[1] 设计模式:可复用面向对象软件的基础
[2] Head First 设计模式