目录
意图
- 将抽象与其实现分离,以便两者可以独立变化。
- 在继承层次中发布接口,并将实现埋在自己的继承层次中。
- 超越封装,到绝缘
问题
通过使用抽象基类的子类化来提供替代实现,已经发生了“软件动脉硬化”。这锁定了接口和实现之间的编译时绑定。抽象和实现不能独立扩展或组合。
动机
考虑“线程调度”的领域。

有两种类型的线程调度程序,以及两种类型的操作系统或“平台”。鉴于这种专业化方法,我们必须为这两个维度的每个排列定义一个类。如果我们添加一个新平台(比如……Java 的虚拟机),我们的层次结构会是什么样子?

如果我们有三种线程调度程序和四种平台呢?如果我们有五种线程调度器和十种平台呢?我们必须定义的类数量是调度方案数量和平台数量的乘积。
Bridge 设计模式建议将这种呈指数爆炸式增长的继承层次结构重构为两个正交的层次结构——一个用于独立于平台的抽象,另一个用于依赖于平台的实现。

讨论
将组件的接口和实现分解为正交的类层次结构。接口类包含一个指向抽象实现类的指针。这个指针是用一个具体实现类的实例来初始化的,但是从接口类到实现类的所有后续交互都仅限于实现基类中维护的抽象。客户端与接口类交互,然后将所有请求“委托”给实现类。
接口对象是客户端已知和使用的“句柄”;而实现对象或“主体”被安全地封装以确保它可以继续发展,或被完全替换(或在运行时共享。
在以下情况下使用桥接模式:
- 你想要实现的运行时绑定,
- 由于耦合接口和众多实现,您会产生大量的类,
- 你想在多个对象之间共享一个实现,
- 您需要映射正交类层次结构。
后果包括:
- 解耦对象的接口,
- 改进的可扩展性(您可以独立扩展(即子类化)抽象和实现层次结构),
- 对客户隐藏细节。
Bridge 是“handle/body”成语的同义词。这是一种将实现类封装在接口类内部的设计机制。前者是主体,后者是手柄。用户将句柄视为实际的类,但工作是在主体中完成的。“句柄/主体类惯用语可用于将复杂的抽象分解为更小、更易于管理的类。惯用语可能反映了控制对它的访问的多个类共享单个资源(例如引用计数)。”
结构
客户不想处理依赖于平台的细节。桥接模式将这种复杂性封装在抽象“包装器”后面。
Bridge 强调从“实现”抽象中识别和解耦“接口”抽象。

例子
桥接模式将抽象与其实现分离,因此两者可以独立变化。控制灯、吊扇等的家用开关就是 Bridge 的一个例子。开关的目的是打开或关闭设备。实际的开关可以实现为拉链、简单的两位开关或各种调光开关。

检查清单
- 确定域中是否存在两个正交维度。这些独立的概念可以是:抽象/平台,或领域/基础设施,或前端/后端,或接口/实现。
- 设计关注点分离:客户想要什么,平台提供什么。
- 设计一个最小的、必要的和足够的面向平台的接口。它的目标是将抽象与平台分离。
- 为每个平台定义该接口的派生类。
- 创建“具有”平台对象并将面向平台的功能委托给它的抽象基类。
- 如果需要,定义抽象类的特化。
经验法则
- 适配器在设计完成后就可以工作;Bridge 让它们先于它们工作。
- Bridge 是预先设计的,让抽象和实现独立变化。改装适配器以使不相关的类一起工作。
- 状态、策略、桥接(以及在某种程度上适配器)具有相似的解决方案结构。它们都共享“句柄/主体”习语的元素。它们的意图不同——也就是说,它们解决不同的问题。
- State 和 Bridge 的结构是相同的(除了 Bridge 允许信封类的层次结构,而 State 只允许一个)。这两种模式使用相同的结构来解决不同的问题:State 允许对象的行为随着其状态而改变,而 Bridge 的目的是将抽象与其实现分离,以便两者可以独立变化。
- 如果接口类委托创建它们的实现类(而不是直接创建/耦合自己),那么设计通常使用抽象工厂模式来创建实现对象。
本文来自转载,原文链接: