桥接模式
桥接模式
一、什么是桥接模式?
桥接模式(Bridge Design Pattern):将抽象与实现解耦,让他们能够独立变化。
或者,桥接模式就是将类的功能层次结构和类的实现层次结构分离开来,降低它们的耦合度。
抽象,即类的功能层次结构,采用的是继承的方式。
实现,即类的实现层次结构,采用的是组合的方式。
1.1 多用组合少用继承
桥接模式,还有通俗一些的解释:一个类存在多个独立变化的维度时,可以通过组合方式让这些维度独立扩展。
比如说,汽车 Car 是一种抽象类型。
它的品牌类型,可以是奔驰、宝马、奥迪等;
而每辆车,它可能有好几个挡位,比如自动档、手动挡、手自一体等。
假设有m种品牌,n种挡位,那么它既可以形成成 m * n 种组合。
如果只采用继承来实现这些组合的话,那就需要有 m * n 个类,如果还有其他维度,那么组合数量会更多。
但是通过桥接模式,将品牌和挡位分离,采用组合的方式的话,就只需要 m + n 个类,大大减少了类的数量。
桥接模式,实际上就是利用组合来避免继承爆炸。
1.2 基于接口编程
如果从结构上来说的话,继承就相当于是一棵树,组合就相当于在树与树之间的连接,它们构成了森林。
每棵树,都是一个维度,都有自己的抽象功能层次结构;
而每个维度之间,又存在着联系,这种联系就是一种实现层次。
树与树之间的联系,一般都是通过顶层的接口抽象来关联的,互相之间是基于接口连接。
桥接模式,实际上是通过接口来进行交互。
二、为什么要用桥接模式?
桥接模式的主要作用有几个:
- 将类的功能层次和实现层次分离,降低耦合度
- 使用组合替代继承,避免组合爆炸的问题
- 把各个维度独立出来,方便进行扩展
使用桥接模式,最主要的就是避免类继承层次过深,而采用组合的方式来避免这种情况。
比如说,有m个维度,每个维度有n种变化,每种变化又包含k种情况,采用继承来做,就需要 m * n * k 个类。
如果将各个维度独立开来,采用组合的方式,就只需要 m + n + k 个类。
而且各个维度可以单独变化扩展,可维护性也会增强。
桥接模式适用于类层次和类关联比较复杂的情况,如果类层次结构很简单,使用桥接模式反而过于复杂。
三、怎么用桥接模式?
桥接模式中的几个角色:
- 抽象化(Abstraction):类功能层次的抽象类,里面包含了一个实现者的引用
- 扩展后的抽象化(Refined Abstraction):在抽象化的基础上扩展了新功能
- 实现者(Implementor):类实现层次的抽象类,被抽象化角色包含在内
- 具体实现者(ConcreteImplememtor):是实现者的具体实现
桥接模式结构:
示例程序结构:
抽象化(Abstraction):
1 | public class Display { |
扩展后的抽象化(Refined Abstraction):
1 | public class CountDisplay extends Display { |
实现者(Implementor):
1 | public abstract class DisplayImpl { |
具体实现者(ConcreteImplememtor):
1 | public class StringDisplayImpl extends DisplayImpl { |
四、桥接模式有什么优缺点?
优点:
- 将类的功能层次和实现层次分离,降低耦合度
- 使用组合替代继承,避免组合爆炸的问题
- 把各个维度独立出来,方便进行扩展
缺点:
- 结构变得复杂了,可读性变差了