意图
将一个大类或一系列紧密相关的类拆分为抽象和实现两个独立的层次结构, 从而能在开发时分别使用。
问题
有一个几何形状Shape
类,从它能扩展出两个子类: 圆形Circle
和方形Square
。 希望对这样的类层次结构进行扩展以使其包含颜色,所以你打算创建名为红色Red
和蓝色Blue
的形状子类。但是由于你已有两个子类,所以总共需要创建四个类才能覆盖所有组合,例如蓝色圆形BlueCircle
和红色方形RedSquare
。
而且在层次结构中新增形状和颜色将导致代码复杂程度指数增长。例如添加三角形状,你需要新增两个子类,也就是每种颜色一个;此后新增一种新颜色需要新增三个子类,即每种形状一个。如此以往,情况会越来越糟糕。
解决方案
桥接模式通过将继承改为组合的方式来解决这个问题。具体来说,就是抽取其中一个维度并使之成为独立的类层次,这样就可以在初始类中引用这个新层次的对象,从而使得一个类不必拥有所有的状态和行为。
在形状类中添加一个颜色类的成员变量,形状类可以将所有与颜色相关的工作委派给连入的颜色对象。 这个成员变量就成为了形状和颜色之间的桥梁,新增颜色将不再需要修改形状类层次。
桥接模式结构
在实际的程序中,抽象部分是图形用户界面(GUI),而实现部分则是底层操作系统代码(API),GUI 层调用API层来对用户的各种操作做出响应。
一般来说, 可以在两个独立方向上扩展这种应用:
- 开发多个不同的 GUI(例如面向普通用户和管理员进行分别配置)
- 支持多个不同的 API(例如, 能够在 Windows、 Linux 和 macOS 上运行该程序)。
用桥接模式将类拆分为两个类层次结构:
- 抽象部分: 程序的 GUI 层。
- 实现部分: 操作系统的 API。
这样做的好处是:无需改动与 API 相关的类就可以修改 GUI 类。此外如果想支持一个新的操作系统, 只需在实现部分层次中创建一个子类即可。
小结
适合应用场景:
- 要拆分或重组一个具有多重功能的庞杂类。
- 希望在几个独立维度上扩展一个类。
- 需要在运行时切换不同实现方法。
优点:
- 开闭原则,可以新增抽象部分和实现部分,且它们之间不会相互影响。
- 单一职责原则,抽象部分专注于处理高层逻辑,实现部分处理平台细节。
- 可以创建与平台无关的类和程序。
- 客户端代码仅与高层抽象部分进行互动,不会接触到平台的详细信息。
缺点:
- 对高内聚的类使用该模式可能会让代码更加复杂。
参考
22种设计模式:refactoringguru.cn/design-patterns
《设计模式:可复用面向对象软件的基础》