桥接模式
桥接模式通过抽象和实现部分的分离,使得两者可以独立变化。抽象部分定义抽象类,维护一个对实现对象的引用。 实现部分定义实现接口,提供不同的实现。这样就可以通过组合不同的抽象类和实现类来创建对象,提高了系统的灵活性。

主要角色:
- 抽象(Abstraction):定义抽象接口,通常包含对实现接口的引用。
- 扩展抽象(RefinedAbstraction):对抽象的扩展,可以是抽象类的子类或具体实现类。
- 抽象实现(Implementor):定义实现接口,提供基本操作的接口。
- 具体实现(ConcreteImplementor):实现实现接口的具体类。
Info
在设计模式中类与类之间的关系主要有6种:依赖、关联、聚合、组合、继承、实现,它们之间的耦合度依次增加。子类必须实现抽象父类中的所有方法,父类抽象方法的变更,必然导致子类的变更。这是一种强关联关系。强关联有必然使我们的系统不易扩展。所以桥梁模式为化解强关联提供了一种解决方案。
桥接模式,抽象和实现的分离,可以理解为功能性的抽象和内部实现的分离。
当组件比较复杂,比如:属性存在复杂的依赖关系时,可以通过桥接模式进行拆分成多个组件。使得每个组件可以单独扩展,以此来简化组件,实现解耦。
代码实现
抽象
interface Implementor {
public void operationImpl();
}扩展抽象
public class ConcreteImplementorA implements Implementor {
@Override
public void operationImpl() {
System.out.println("ConcreteImplementorA operation");
}
}抽象实现
public abstract class Abstraction {
protected Implementor impl;
public void setImplementor(Implementor impl) {
this.impl = impl;
}
abstract public void operation();
}这里聚合了Implementor,通过该类来实现我们的具体功能。
具体实现
public class RefinedAbstraction extends Abstraction {
public void operation() {
// do something
impl.operationImpl();
}
}在抽象功能的实现类中,调用内部实现方法,完成operation的操作。
使用
public class Client {
public static void main(String[] args) {
Abstraction abstraction = new RefinedAbstraction();
abstraction.setImplementor(new ConcreteImplementorA());
abstraction.operation();
}
}Abstraction和Implementor是Bridge模式中定义的两个抽象/接口,用于解耦抽象部分和实现部分。
为了保证原有组件的功能,在Abstraction中聚合Implementor,除了实现Abstraction自身的功能,通过调用Implementor的方法来完成其他功能。
这样Abstraction和Implementor可以独立变化,提高了系统的灵活性。
与其他设计模式的对比
桥接模式 vs 适配器模式
| 特性 | 桥接模式 | 适配器模式 |
|---|---|---|
| 目的 | 分离抽象与实现,使两者独立变化 | 兼容接口不匹配的类 |
| 实现时间 | 设计阶段考虑使用 | 已有类接口不匹配时使用 |
| 接口关系 | 抽象与实现是平行的,无继承关系 | 适配器与适配者有继承或组合关系 |
| 扩展性 | 高(抽象和实现可独立扩展) | 中(主要解决接口不兼容问题) |
| 适用场景 | 系统需要跨越多个维度变化 | 已有系统需要集成新接口 |
桥接模式 vs 装饰器模式
| 特性 | 桥接模式 | 装饰器模式 |
|---|---|---|
| 目的 | 分离抽象与实现,使两者独立变化 | 动态扩展对象功能 |
| 结构 | 抽象类持有实现接口的引用 | 装饰器包装原对象,保持接口一致 |
| 继承关系 | 避免了多层继承 | 基于组合优于继承的原则 |
| 扩展性 | 高(两个维度独立扩展) | 高(可动态添加多个装饰器) |
| 适用场景 | 系统需要跨越多个维度变化 | 需要动态扩展对象功能而不修改原类 |
桥接模式 vs 策略模式
| 特性 | 桥接模式 | 策略模式 |
|---|---|---|
| 目的 | 分离抽象与实现,使两者独立变化 | 定义算法家族,使算法可互相替换 |
| 关注点 | 抽象与实现的分离 | 算法的封装与替换 |
| 结构 | 抽象类持有实现接口的引用 | 上下文持有策略接口的引用 |
| 扩展性 | 高(两个维度独立扩展) | 高(可扩展新的算法) |
| 适用场景 | 系统需要跨越多个维度变化 | 需要在运行时选择不同算法 |
总结
桥接模式是一种结构型设计模式,它通过将抽象部分与实现部分分离,使它们可以独立地变化。这种模式的核心思想是使用组合关系代替继承关系,从而避免了继承带来的强耦合问题。
核心思想
将抽象部分与实现部分分离,使它们可以独立地变化,通过组合关系代替继承关系,实现抽象与实现的解耦。
主要角色
- 抽象(Abstraction):定义抽象接口,通常包含对实现接口的引用,维护抽象部分的功能。
- 扩展抽象(RefinedAbstraction):对抽象的扩展,可以是抽象类的子类或具体实现类,实现抽象部分的具体功能。
- 实现接口(Implementor):定义实现接口,提供基本操作的接口,隐藏具体实现细节。
- 具体实现(ConcreteImplementor):实现实现接口的具体类,提供具体的实现逻辑。
优点
- 分离抽象与实现:使抽象部分和实现部分可以独立地扩展和变化。
- 减少继承层次:通过组合关系代替继承关系,避免了多层继承带来的复杂性。
- 提高系统灵活性:可以动态地组合不同的抽象类和实现类,以满足不同的需求。
- 符合开闭原则:扩展抽象部分或实现部分时,不需要修改原有代码。
缺点
- 增加系统复杂度:引入了更多的类和接口,增加了系统的理解和设计难度。
- 需要正确识别抽象与实现:需要准确地识别系统中的抽象部分和实现部分,否则可能导致设计不当。
适用场景
- 系统需要跨越多个维度变化:当系统需要在多个维度上进行扩展时,桥接模式可以有效地减少类的数量。
- 避免多层继承导致的类爆炸:当使用继承会导致大量子类时,桥接模式是一个更好的选择。
- 希望抽象与实现独立变化:当抽象部分和实现部分需要独立地扩展和变化时,桥接模式可以提供很好的支持。
实际应用
在实际开发中,桥接模式常用于:
- GUI开发中,窗口抽象与底层实现的分离
- 数据库驱动程序中,数据库访问抽象与具体数据库实现的分离
- 操作系统中,文件系统抽象与具体存储设备实现的分离
- 网络通信中,协议抽象与具体传输方式实现的分离