Bridge模式
目录 |
1 问题
总结面向对象实际上就两句话:一是松耦合(Coupling),二是高内聚(Cohesion)。面向对象系统追求的目标就是尽可能地提高系统模块内部的内聚(Cohesion)、尽可能降低模块间的耦合(Coupling)。然而这也是面向对象设计过程中最为难把握的部分,大家肯定在OO系统的开发过程中遇到这样的问题:
- 客户给了你一个需求,于是使用一个类来实现(A);
- 客户需求变化,有两个算法实现功能,于是改变设计,我们通过一个抽象的基类,再定义两个具体类实现两个不同的算法(A1和A2);
- 客户又告诉我们说对于不同的操作系统,于是再抽象一个层次,作为一个抽象基类A0,在分别为每个操作系统派生具体类(A00和A01,其中A00表示原来的类A)实现不同操作系统上的客户需求,这样我们就有了一共4个类。
- 可能用户的需求又有变化,比如说又有了一种新的算法……..
- 我们陷入了一个需求变化的郁闷当中,也因此带来了类的迅速膨胀。
Bridge模式则正是解决了这类问题。
2 功能
将抽象部分与它的实现部分分离,使它们都可以独立地变化。
3 结构图

在Bridge模式的结构图中可以看到,系统被分为两个相对独立的部分,左边是抽象部分,右边是实现部分,这两个部分可以互相独立地进行修改:例如上面问题中的客户需求变化,当用户需求需要从Abstraction派生一个具体子类时候,并不需要像上面通过继承方式实现时候需要添加子类A1和A2了。另外当上面问题中由于算法添加也只用改变右边实现(添加一个具体化子类),而右边不用在变化,也不用添加子类,一切都变得Elegant!
4 示例代码
namespace DesignPattern_Bridge { // class Implementor class Implementor { public: virtual void OperationImp() = 0 ; } ; // class ConcreteImplementorA class ConcreteImplementorA : public Implementor { public: virtual void OperationImp() {} } ; // class ConcreteImplementorB class ConcreteImplementorB : public Implementor { public: virtual void OperationImp() {} } ; // class Abstraction class Abstraction { public: void Operation(Implementor* imp) { assert(imp) ; imp->OperationImp() ; } } ; }
客户端代码:
{ using namespace DesignPattern_Bridge ; Abstraction obj ; Implementor *impa = new ConcreteImplementorA() ; Implementor *impb = new ConcreteImplementorB() ; obj.Operation(impa) ; //第一种实现方法 obj.Operation(impb) ; //第二种实现方法 }
5 实例
创建可以在X Window System和IBM的Presentation Manager系统中都可以使用的窗口。(书上的例子)

Bridge的魅力在于抽象和实现之间是松散的关系,它们之间可以进行随意组合。如上图中,就有IconWindow+XWindowImp、TransientWindow+XWindowImp、IconWindow+PMWindowImp、TransientWindow+ PMWindowImp四种组合。
6 讨论
Bridge是设计模式中比较复杂和难理解的模式之一,也是OO开发与设计中经常会用到的模式之一。使用组合(委托)的方式将抽象和实现彻底地解耦,这样的好处是抽象和实现可以分别独立地变化,系统的耦合性也得到了很好的降低。
GoF在说明Bridge模式时,在意图中指出Bridge模式“将抽象部分与它的实现部分分离,使得它们可以独立地变化”。这句话很简单,但是也很复杂,连Bruce Eckel在他的大作《Thinking in Patterns》中说“Bridge模式是GoF所讲述得最不好(Poorly-described)的模式”,个人觉得也正是如此。原因就在于GoF的那句话中的“实现”该怎么去理解:“实现”特别是和“抽象”放在一起的时候我们“默认”的理解是“实现”就是“抽象”的具体子类的实现,但是这里GoF所谓的“实现”的含义不是指抽象基类的具体子类对抽象基类中虚函数(接口)的实现,是和继承结合在一起的。而这里的“实现”的含义指的是怎么去实现用户的需求,并且指的是通过组合(委托)的方式实现的,因此这里的实现不是指的继承基类、实现基类接口,而是指的是通过对象组合实现用户的需求。理解了这一点也就理解了Bridge模式,理解了Bridge模式,你的设计就会更加Elegant了。
实际上上面使用Bridge模式和使用带来问题方式的解决方案的根本区别在于是通过继承还是通过组合的方式去实现一个功能需求。因此面向对象分析和设计中有一个原则就是:Favor Composition Over Inheritance。其原因也正在这里。
7 参见
- c++设计模式(2)-Bridge. Henry. 2008-08-29 22:53.
- 设计模式解析之——BRIDGE 模式. K_Eckel. 2005-04-05.