一种基于最小设计原则的结构型设计模式.
Bridge: 将实现与抽象放在两个不同的类层级, 使两个层次可以独立改变.
所谓实现, 指的是对接口的Implementation, 所谓抽象, 可以是某个供具体子类继承的抽象类. 而在这个抽象类和接口之间的Bridge, 则一般通过组合/聚合的方式的实现.
于是就有了以下角色:
- Implementor
- 一个能够概括Abstraction及其子类行为的接口, 内部的方法可以仅提供基本操作
- ConcreteImplementor
- 一个/多个实现Implementor方法的具体类, 细粒度更高, 而业务则属于同一类
- Abstraction
- 定义抽象类的接口, 对Implementor产生依赖
- 一般会在这个抽象类的方法里直接调用Implementor的方法
- RefinedAbstraction
- 继承Abstraction, 扩充功能, 完成桥梁的另一头.
- 显然你也可以不使用这个角色
上面的角色定义的隐含信息就是: 如果你无法找到桥梁的两头, 使用Bridge是费力不讨好的.
**
一个例子
假设我们现在要重新创造加拉帕戈斯群岛上的物种. 你已经知道了鸟会下蛋, 哺乳类是胎生, 鱼类也是产卵, 但行为和鸟并不相同. 如果使用面向对象的方式定义Animal, 再让Bird, Mammals, Fishes去继承Animal, 那么每个子类都必须创造专属于自己的行为, 而如果你还想引入Insects和它成千上万种子类, 就会产生庞大而臃肿的继承链.
为什么? 因为繁殖(reproduction)行为是一种实现, 而Animal则是一种抽象, 按照继承的做法,相当于手动去给实现和抽象牵线搭桥.
让我们试一试桥接模式吧:
在Bridge的关键点, 充当Abstraction的Animal中, 使用Reproduction的方法:
public class Animal {
private Reproduction rep;
public Animal(Reproduction rep){this.rep = rep;}
public void copulate(){
rep.copulate();
}
public void procreate(){
rep.procreate();
}
}
如果具体的Bird和Mammal还想进一步控制行为的话, 可以继续覆写:
public class Bird {
public Bird(Reproduction rep){super(rep);}
public void copulate(){
super.copulate();
// Do Stuff
}
public void procreate(){
super.procreate();
// Do Stuff
}
}
实际上是Bird和FlyingCreature之间有了Bridge, 而两个部分都可以独立改变, Bird可以增加字段,方法而不必考虑FlyingCreature, 因为Bird通过Abstraction的角色获得FlyingCreature的方法.
相关模式
Abstract Factory可以创建和配置一个特定的Bridge模式.
Adapter侧重于帮助无关的类协同工作, 通常是系统设计完后的行为. 而Bridge则是系统设计时就开始使用, 一旦完成Bridge模式, 系统可以直接工作.