l 抽象化(Abstraction)角色:抽象化给出的定义,并保存一个对实现化对象的引用。
l 修正抽象化(Refined Abstraction)角色:扩展抽象化角色,改变和修正父类对抽象化的定义。
l 实现化(Implementor)角色:这个角色给出实现化角色的接口,但不给出具体的实现。必须指出的是,这个接口不一定和抽象化角色的接口定义相同,实际上,这两个接口可以非常不一样。实现化角色应当只给出底层操作,而抽象化角色应当只给出基于底层操作的更高一层的操作。
l 具体实现化(Concrete Implementor)角色:这个角色给出实现化角色接口的具体实现。
动机
当一个对象有了两个变化的维度,如何应对这种“多维度的变化”?如何利用面向对象技术来使得这个对象类型可以轻松沿着多个方向变化,而不引入额外的复杂度?
意图
将抽象部分与实现部分分离,使它们都可以独立地变化。
示意性代码
示意性代码
实例
该例子演示了业务对象(BusinessObject)通过Bridge模式与数据对象(DataObject)解耦(相分离)。数据对象的实现可以在不改变客户端代码的情况下动态进行更换。
一个实例
Bridge模式的几个要点:
1、Bridge模式使用“对象间的组合关系”解耦了抽象和实现之间固有的绑定关系,使得抽象和实现可以沿着各自的维度来变化。
2、所谓抽象和实现沿着各自纬度的变化,即“子类化”它们。得到各个子类之后,便可以任意重组它们,从而获得不同平台上的不同型号。
3、Bridge模式有时候类似于多继承方案,但是多继承方案往往违背单一职责原则(即一个类只有一个变化的原因),复用性比较差。Bridge模式是比多方案更好的解决方法。
4、Bridge模式的应用一般在“两个非常强的变化维度”,有时候即使有两个变化的维度,但是某个方向的变化维度并不剧烈,换言之两个不会导致纵横交错的结果,并不一定要使用Bridge模式。
我的理解
当对象的抽象部分和实现部分都发生变化时,也就是发生二维变化。假设将变化出M种抽象,N种表现。一般的解决方法是派生出M×N个对象,以满足条件,这个结构遵循了开放-封闭原则,但是它却违背了单一职责原则,即一个类只有一个引起它变化的原因, 抽象部分(即固有的状态和行为)发生变化整个类要变,实现部分( 即类在客户环境下的不同表现)发生变化,整个类也要变。一种更好的解决方案是:将抽象部分与实现部分分离,这样就只需要M+N个对象,通过实现部分与抽象部分的任意组合,得到客户期望的表现。
参考资料
《.NET设计模式(9):桥接模式(Bridge Pattern)》 TerryLee
《设计模式(16)-Bridge Pattern》 吕震宇
《C#面向对象设计模式纵横谈系列课程(8)》 李建中老师