桥接模式的原理非常简单,但是使用起来会有一定的难度,所以相对于适配器模式来说,在理解桥接模式时,重点要能跳出局部,多从整体结构上去思考。
一、模式原理分析
桥接模式的定义是:将抽象部分与它的实现部分分离,使它们都可以独立地变化。
不过,这里的抽象常常容易被理解为抽象类,并将实现理解为继承后的“派生类”,但是这样理解存在局限性,因为 GoF 的本意是想表达“从对象与对象间的关系去看,做抽象实体与抽象行为的分离”,所以使用抽象实体和抽象行为来描述更为准确。
我们来看看桥接模式的 UML 描述,如下图所示:
从该图中,我们可以看到桥接模式主要包含了以下四个关键角色。
-
抽象实体:定义的一种抽象分类。比如,电脑中的 CPU、内存、摄像头、显示屏等。
-
具体实体:继承抽象实体的子类实体。比如,Intel i7 CPU、三星内存、徕卡摄像头、京东方显示屏幕等。
-
抽象行为:定义抽象实体中具备的多种行为。比如,CPU 逻辑运算、内存读写存储、摄像头拍照、屏幕显示图像等。
-
具体行为:实现抽象行为的具体算法。比如,Intel 使用 X64 架构实现 CPU 逻辑运算,Mac M1 芯片使用 ARM 架构实现 CPU 逻辑运算,等等。
桥接模式原理的核心是抽象与抽象之间的分离,这样分离的好处就在于,具体的实现类依赖抽象而不是依赖具体,满足 DIP 原则,很好地完成了对象结构间的解耦。换句话说,抽象的分离间接完成了具体类与具体类之间的解耦,它们之间使用抽象来进行组合或聚合,而不再使用继承。
下面我们再来看看桥接模式对应 UML 图的代码实现,具体如下:
public abstract class AbstractEntity {
//行为对象
protected AbstractBehavior myBehavior;
//实体与行为的关联
public AbstractEntity(AbstractBehavior aBehavior) {
myBehavior = aBehavior;
}
//子类需要实现的方法
public abstract void request();
}
public class DetailEntityA extends AbstractEntity {
public DetailEntityA(AbstractBehavior aBehavior) {
super(aBehavior);
}
@Override
public void request() {
super.myBehavior.operation1();
}
}
public class DetailEntityB extends Ab