在你的类设计过程中,如果发现有两组类,它们的概念是正交的话,可以使用桥模式来完成两组类的解耦合,让它们可以各自独立变化。
这里的概念里面,重点需要理解的是正交。什么是正交?「正交」是一个数学概念,就是说两条线是垂直的。在一个正交系统里,沿着一个方向的变化,其另外一个方向不会发生变化。这里引入正交的意思是,当两组类中的一种引发变化时,不会影响到另外一组类。引入正交的设计,意味着单一的变化,不会引发到处的修改,而是局限于特定的范围内。
这样,都可以使用一个接口当成桥梁,通过它把两组类分离,让它们可以在变化时互相可以不影响。假设我们要做一个ShapeEditor,其中的形状有圆形和矩形等,可以使用红色和绿色来绘制它。在这里,正交的两组类,就是Shape类和DrawApi类,前者规定形状的定义,后者规定形状的绘制。我们希望增加新的绘制颜色是,不需要影响到Shape系列的类。此时就可以采用Bridge。
此案例中,扮演桥的角色的就是DrawApi接口,它搭建了两个正交方向类的桥梁。两个正交方向分别是Shape系列类(包括Circle)和DrawAPI系列类(包括RedCircle,GreenCircle)。当添加新的颜色比如BlueCircle时,无需在Shape内添加类,因此不会影响到Shape系列类。这意味着,两个正交方向的类,可以自由变化,而不必影响到另外一个方向。
桥模式遵循的是一个比较古老的建议,就是“组合优于继承”,同样的问题,一个不建议的方法,就是使用继承。这意味着:
shape/ \ Circle Rect/ \ / \RedCircle GreenCircle RedRect GreenRect复制代码
当引入新的颜色时,会导致指数级的类数量爆炸。也会导致本来两个正交的类,现在完全的粘合在一起,任何一个变化,都会导致另外一个方向的类的变化。
只要是设计内有两个正交的概念,就可以考虑使用桥模式。形状和绘制方法,行为和平台,文件格式和序列化方法,都是这样的正交概念。
行为和平台的典型案例是线程调度器和对应的平台。线程如何调度和线程的所在平台是两个独立的概念。一种方案是:
当添加新的调度方案和平台时,也会导致类数量膨胀。
把两个正交方向分开,使用Bridge桥接它们,就可以解决这个问题。
另一个案例,是应用模块和色彩模式,使用继承的方式:
疑难解析:
GoF定义的桥模式,是这样的:桥模式用来解耦抽象和实现以便两者可以分别变化。这里抽象指的是Abstraction和RedefinedAbstraction两个类,而实现指的是Implementor接口和ConcreteImplement实现。
这里的“抽象”和“实现”是比较容易误解的。它不是我们通常认为的“抽象就是接口或者抽象类,实现就是类”。GoF定义是语言独立的,在这里要忘掉计算机语言的定义。简单的理解抽象和具体是正交的两个方向就好了。
其中的图来自tutorialpoint等。在此鸣谢。