桥接模式的定义
将抽象部分与它的实现部分分离,使它们都可以独立地变化。
使用场景
以下情况使用Bridge模式
- 你不希望在抽象和它的实现部分之间有一个固定的绑定关系。例如这种情况可能是因为,在程序运行时刻实现部分应可以被选择或者切换。
- 类的抽象以及它的实现都应该可以通过生成子类的方法加以扩充。这时Bridge模式让你可以对不同的抽象接口和实现部分进行组合,并分别对它们进行扩充。
- 对一个抽象的实现部分的修改应对客户端不产生影响,即调用者的代码不必重新编译。
- 有大量的类要生成,这种类的继承关系印证了将对象拆分成多个部分的需求
- 你想在多个对象之间共享实现又想对调用者隐藏细节时
结构
桥接模式结构如下
Abstraction
– 定义抽象类的接口。
– 维护一个指向Implementor类型对象的引用。RefinedAbstraction
– 扩充由Abstraction定义的接口。Implementor
– 定义实现类的接口,该接口不一定要与Abstraction的接口完全一致;事实上这两个接口可以完全不同。一般来讲,Implementor接口仅提供基本操作,而Abstraction则定义了基于这些基本操作的较高层次的操作。ConcreteImplementor
– 实现Implementor接口并定义它的具体实现。
协作
Abstraction将Client的请求转发给它的Implementor对象。
效果
分离接口及其实现部分
一个实现未必不变地绑定在一个接口上。抽象类的实现可以在运行时刻进行配置,一个对象甚至可以在运行时刻改变它的实现。
将Abstraction与Implementor解耦有助于降低在编译时对实现部分的依赖性,当改变一个实现类时,并不需要重新编译Abstraction类和它的客户程序。为了保证一个类库的不同版本之间的二进制兼容性,一定要有这个性质。
另外,接口与实现分离有助于分层,从而产生更好的结构化系统,系统的高层部分仅需知道Abstraction和Implementor即可。增加可扩展性
你可以独立地对Abstraction和Implementor层次结构进行扩展。- 实现细节对客户透明
你可以对客户隐藏实现细节
桥接模式实现(Implement)
案例
现在要开发一款画图工具,首先有一些形状,比如正方形、三角形、圆形,形状有各种各样的颜色,比如红色、蓝色、绿色,形状还有自己的边框,虚线或者实线的,也就是说形状有三种,颜色也有三种,边框有两种,这样的话一共有3x3x2=18种类型的形状了,如果对他们一一创建类的话十分复杂,这还不算特别多,如果再增加几种颜色或形状,类的数量就无法承受了。所以,桥接模式在这里就派上用场了。
结构
案例结构如下
代码实现
Shape类
Round类
Color类
Blue类
Border类
DottedLineBorder类
画出蓝色虚线边框的圆
总结
由例子可以看到我们在画圆的时候,可以动态的指定颜色和边框类型,并且抽象方法color()与具体颜色的实现applyColor()分离了,同样drawBorder()与具体边框类型的实现也分离了,并且对调用者隐藏了内部实现细节,调用者只需要调用color()方法和drawBorder()方法就可以了。假如还有其他的属性需要动态变化调整,甚至可以使用set方法进行设置。除此之外,扩展性也变好了,如果需要增加颜色,只需要增加实现Color的类即可。桥接模式使得系统内的抽象与实现之间的关系更加灵活,不同于Adapter模式,桥接模式在设计阶段就应该好好考虑使用,这也使得系统的扩展性更好。