首页/开发/代码质量与评审速查/桥接模式 Bridge(结构型)
设计原则与模式62 条

桥接模式 Bridge(结构型)

把抽象(做什么)与实现(怎么做)分离为两条独立的继承体系:维度一(如形状)与维度二(如渲染引擎)各自扩展,组合而非相乘。

桥接模式解决什么

桥接模式(Bridge)把「做什么」与「怎么做」拆成两条独立的继承体系,再通过组合把它们关联起来。它要处理的典型困境是两个维度都在扩展:如果按维度相乘来派生子类,类型数量会迅速失控。把其中一个维度作为抽象层持有另一个维度的引用后,两侧可以各自演进,组合方式在运行时决定。

基本信息

意图抽象与实现解耦,两条体系独立演化
典型信号两个维度都在扩展,子类数量呈相乘关系
实现方式抽象层持有一个实现层引用,调用时委托过去
与策略的差别策略面向算法替换,桥接强调体系级的维度拆分

典型使用场景

  • 图形与渲染后端:形状有圆形、矩形,渲染有矢量与位图,两个维度各自扩展而不是相乘
  • 消息与发送渠道:消息类型与短信、邮件等通道分离,新增通道不影响消息类型
  • 数据导出与文件格式:报表类型与输出格式两条体系,格式新增不必改报表类
  • 跨平台界面控件:控件类型与平台实现分离,移植新平台只需增加实现层
  • 设备驱动:设备能力与具体硬件实现分离,便于替换与模拟

结构示意

结构示意
// 维度一:抽象(做什么),持有维度二的引用
abstract class Shape {
    protected final Renderer renderer;   // 组合而非继承
    Shape(Renderer r) { this.renderer = r; }
    abstract void draw();
}

// 维度二:实现(怎么做),可独立扩展
interface Renderer { void renderCircle(); void renderSquare(); }

与相邻模式对照

模式关注点分辨方式
Bridge两个维度各自扩展子类数量是否呈相乘关系
Strategy单个算法族可替换只有一条变化轴,替换发生在调用时
Adapter接口不兼容的转换目的是让既有类能配合使用,不是拆分维度
Abstract Factory产品族的一致性解决一组相关对象如何成套创建
Decorator同一接口叠加行为不新增维度,只在外层追加职责
只有一个维度存在扩展压力时不需要桥接:抽象层没有对应的变化来源,反而多出一层间接调用。判断依据是两侧是否都在持续新增类型。
拆成两条体系后要避免它们互相引用:若抽象层直接访问实现层的具体类型,或实现层反过来依赖抽象层的细节,解耦目标就落空了,改动又会沿着依赖链扩散。

落地检查清单

  • 两个维度都能各自新增类型而不修改对方
  • 抽象层只依赖实现层的接口,不依赖具体实现
  • 新增一个维度取值时,改动局限在一条体系内
  • 组合关系在运行时可以替换,便于测试与灰度

易错点

  • 只有一个维度就搭桥:抽象层没有扩展压力,平白增加一层转发,阅读时需要跨两个文件才能看懂一次调用
  • 两条体系又互相引用:解耦目标落空,两侧改动依旧互相牵连
  • 把桥接当继承的替代品全量套用:简单的一维扩展被拆成两套类型,定位实现的路径变长
  • 实现层接口设计过宽:抽象层被迫依赖它用不到的方法,等于把耦合换到新位置

数据来源与参考

  • 《设计模式》(GoF)· Bridge
​‌‌​​‌​​​‌‌​‌‌‌‌​‌‌​​​‌‌​‌‌‌​​‌‌​​‌​‌‌‌​​‌‌‌​​​‌​‌‌​‌​​‌​‌‌‌​​​‌​‌‌​‌​​‌​‌‌​​​‌‌​‌‌‌​‌​​​‌‌​‌‌‌‌​​‌​‌‌‌​​‌‌​​​‌‌​‌‌​‌‌‌‌​‌‌​‌‌​‌