一:概念
桥接模式,又叫桥梁模式,顾名思义,就是有座“桥”,那这座桥是什么呢?就是一条聚合线(下方UML图),比如我们下面会举的例子,手机有手机品牌和手机游戏等等,每个手机品牌都有多款游戏,那是不是二者之间就是聚合关系了,这是合成/聚合复用原则的体现,当我们发现类有多层继承时就可以考虑使用桥接模式,用聚合代替继承。
桥接模式(Bridge),将抽象部分与它的实现部分分离,使它们都可以独立地变化。UML结构图如下:
二:演进
示例:
画图,这里有一个画笔,可以画正方形、长方形、圆形。同时可以给图形上色,这里有三种颜色:白色、灰色、黑色。这里我们可以画出3*3=9中图形:白色正方形、白色长方形、白色圆形。。。。。。
到这里了我们几乎到知道了这里存在两种解决方案:
- 方案一:为每种形状都提供各种颜色的版本。
- 方案二:根据实际需要对颜色和形状进行组合。
对于第一种方案,我们需要各种实现九种,如果在增加形状或颜色,那么会导致类爆炸。
对于方案二,采用组合的方式:
这时我们就用到了桥接模式,当形状或则颜色两个维度变化时,我们可以进行组合实现,避免了类爆炸。
三:示例
按照绘图来实现实例:
这里我们将颜色作为Implementor
public interface Color {
void desc(String shapeName);
}
//实现
public class RedColor implements Color {
public void desc(String shapeName) {
System.out.println("红色的" + shapeName);
}
}
public class YellowColor implements Color {
public void desc(String shapeName) {
System.out.println("黄色的" + shapeName);
}
}
public class BlueColor implements Color {
public void desc(String shapeName) {
System.out.println("蓝色的" + shapeName);
}
}
形状作为抽象Abstraction
public abstract class Shape {
protected final Color color;
public Shape(Color color) {
this.color = color;
}
public abstract void draw();
}
抽象的具体实现:
//长方形
public class RectangleShape extends Shape {
public RectangleShape(Color color) {
super(color);
}
@Override
public void draw() {
color.desc("长方形");
}
}
//三角形
public class TriangleShape extends Shape {
public TriangleShape(Color color) {
super(color);
}
@Override
public void draw() {
color.desc("三角形");
}
}
client:
public class BradgeDemo {
public static void main(String[] args) {
RedColor redColor = new RedColor();
Shape rectangleShape = new RectangleShape(redColor);
rectangleShape.draw();
Shape triangleShape = new TriangleShape(redColor);
triangleShape.draw();
}
}
四、 模式优缺点
优点
- 分离抽象接口及其实现部分。提高了比继承更好的解决方案。
- 桥接模式提高了系统的可扩充性,在两个变化维度中任意扩展一个维度,都不需要修改原有系统。
- 实现细节对客户透明,可以对用户隐藏实现细节。
缺点
- 桥接模式的引入会增加系统的理解与设计难度,由于聚合关联关系建立在抽象层,要求开发者针对抽象进行设计与编程。
- 桥接模式要求正确识别出系统中两个独立变化的维度,因此其使用范围具有一定的局性。
五、 模式使用场景
- 如果一个系统需要在构件的抽象化角色和具体化角色之间增加更多的灵活性,避免在两个层次之间建立静态的继承联系,通过桥接模式可以使它们在抽象层建立一个关联关系。
- 对于那些不希望使用继承或因为多层次继承导致系统类的个数急剧增加的系统,桥接模式尤为适用。
- 一个类存在两个独立变化的维度,且这两个维度都需要进行扩展。
六、 模式总结
- 桥接模式实现了抽象化与实现化的脱耦。他们两个互相独立,不会影响到对方。
- 对于两个独立变化的维度,使用桥接模式再适合不过了。
- 对于"具体的抽象类"所做的改变,是不会影响到客户。