桥接模式是一种结构型设计模式, 又称为柄体(Handle and Body)模式或接口(Interface)模式。桥接模式,可将将抽象部分与它的实现部分分离,使它们都可以独立地变化。如将一个大类或一系列紧密相关的类拆分为抽象和实现两个独立的层次结构,从而在开发时分别使用。
Bridge is a structural design pattern that separates the abstract part and the implementation part,
allowing them to change independently.
结构设计
桥接模式包含如下角色:
Abstraction:抽象类,抽象部分,提供高层控制逻辑,依赖于完成底层实际工作的实现对象。
RefinedAbstraction:扩充抽象类,提供控制逻辑的变体。 与其父类一样, 它们通过通用实现接口与不同的实现进行交互。
Implementor:实现类接口,实现部分,为所有具体实现声明通用接口。抽象部分仅能通过在这里声明的方法与实现对象交互。抽象部分可以列出和实现部分一样的方法,但是抽象部分通常声明一些复杂行为,这些行为依赖于多种由实现部分声明的原语操作。
ConcreteImplementor:具体实现类,包括特定于平台或场景的代码。
桥接模式类图表示如下:
伪代码实现
接下来将使用代码介绍下桥接模式的实现。
// 1、抽象部分,提供高层控制逻辑
public class Abstraction {
protected Implementor implementor;
public Abstraction(Implementor implementor) {
this.implementor = implementor;
}
public void operation() {
implementor.operationImp();
}
}
// 2、实现部分,为所有具体实现声明通用接口
public interface Implementor {
void operationImp();
}
// 4、具体实现类,包括特定于平台或场景的代码
public class RefinedAbstraction extends Abstraction {
public RefinedAbstraction(Implementor implementor) {
super(implementor);
}
@Override
public void operation() {
this.implementor.operationImp();
}
}
// 5、客户端调用
public class BridgeClient {
public void test() {
// (1) 指定抽象部分并绑定具体的实现部分
Abstraction abstraction1 = new RefinedAbstraction(new ConcreteImplementorA());
// (2) 调用抽象部分接口
abstraction1.operation();
}
}
适用场景
在以下情况可以考虑使用桥接模式:
(1) 如果想要拆分或重组一个具有多重功能的庞杂类(例如需要与多个数据库进行交互的类),可以考虑使用桥接模式。
桥接模式可以将庞杂类拆分为几个类层次结构。 此后, 你可以修改任意一个类层次结构而不会影响到其他类层次结构。 这种方法可以简化代码的维护工作, 并将修改已有代码的风险降到最低。
(2) 如果希望在几个独立维度上扩展一个类, 可以考虑使用桥接模式。
桥接建议将每个维度抽取为独立的类层次。 初始类将相关工作委派给属于对应类层次的对象, 无需自己完成所有工作。
(3) 如果需要在运行时切换不同实现方法, 可以考虑使用桥接模式。
当然并不是说一定要实现这一点, 桥接模式可替换抽象部分中的实现对象, 具体操作就和给成员变量赋新值一样简单。
顺便提一句, 最后一点是很多人混淆桥接模式和策略模式的主要原因。 记住, 设计模式并不仅是一种对类进行组织的方式, 它还能用于沟通意图和解决问题。
(4) 如果一个系统需要在构件的抽象化角色和具体化角色之间增加更多的灵活性,避免在两个层次之间建立静态的继承联系,通过桥接模式可以使它们在抽象层建立一个关联关系。
(5) 抽象化角色和实现化角色可以以继承的方式独立扩展而互不影响,在程序运行时可以动态将一个抽象化子类的对象和一个实现化子类的对象进行组合,即系统需要对抽象化角色和实现化角色进行动态耦合。
(6) 一个类存在两个独立变化的维度,且这两个维度都需要进行扩展。
(7) 虽然在系统中使用继承是没有问题的,但是由于抽象化角色和具体化角色需要独立变化,设计要求需要独立管理这两者。
(8) 对于那些不希望使用继承或因为多层次继承导致系统类的个数急剧增加的系统,桥接模式尤为适用。
优缺点
桥接模式有以下优点:
(1) 符合开闭原则。分离抽象接口及其实现部分。开发者可以单独新增抽象部分和实现部分,它们之间不会相互影响。
(2) 符合单一职责原则。抽象部分专注于处理高层逻辑, 实现部分处理平台细节。
(3) 提高了代码的可扩展性。在抽象部分或实现部分任意扩展一个维度,都不需要修改原有系统。
(4) 提高了代码的透明性。 实现细节对客户透明,可以对用户隐藏实现细节。
(5) 提高了代码的复用性。桥接模式有时类似于多继承方案,但是多继承方案违背了类的单一职责原则(即一个类只有一个变化的原因),复用性比较差,
而且多继承结构中类的个数非常庞大,桥接模式是比多继承方案更好的解决方法。
但是桥接模式也存在以下缺点:
(1) 代码复杂度上升。比如对高内聚的类使用该模式可能会使代码更加复杂。
(2) 增加系统的理解与设计难度,由于聚合关联关系建立在抽象层,要求开发者针对抽象进行设计与编程。
(3) 桥接模式要求正确识别出系统中两个独立变化的维度,因此其使用范围具有一定的局限性。
参考
《设计模式:可复用面向对象软件的基础》 Erich Gamma, Richard Helm, Ralph Johnson, John Vlissides 著 李英军, 马晓星 等译
https://refactoringguru.cn/design-patterns/bridge 桥接模式
https://design-patterns.readthedocs.io/zh_CN/latest/structural_patterns/bridge.html 桥接模式
https://www.cnblogs.com/adamjwh/p/9033548.html 简说设计模式——桥接模式
https://blog.csdn.net/ShuSheng0007/article/details/88370067 秒懂设计模式之桥接模式
https://www.runoob.com/design-pattern/bridge-pattern.html 桥接模式