← 返回题目列表

桥接模式相比继承有什么优势?

高频 中等 第 9 / 25 题 更新于 2026/07/28
桥接模式继承组合优于继承

简化版

桥接模式相比继承的优势是降低耦合、减少组合类、提升扩展性。继承会把多个变化维度固化在类层级里,桥接用组合让不同维度在运行时连接,更灵活也更容易维护。

详细版

继承适合表达稳定的“is-a”关系,但不适合表达多个维度的自由组合。

例如:

  • Circle 是一种 Shape,这种继承关系相对自然。
  • SvgCircle 既代表 SVG 又代表 Circle,把两个维度压在一个类名里,扩展时会膨胀。

桥接模式把一个维度放在抽象层,另一个维度放在实现接口里。新增实现方式不需要改抽象层,新增抽象类型也不需要改实现层。

完整版教学

一、继承的优势和边界

继承并不是坏设计。它适合表达清晰、稳定、层次不深的类型关系。

例如:

Shape
├── Circle
└── Rectangle

如果系统只关心图形类型,这样写很直接。

但当图形还要支持多种渲染方式时,继续用继承表达组合就会变重。继承层级一旦承载太多维度,类就会越来越细碎。

二、继承方案的主要问题

继承表达多维度组合时有几个典型问题:

  • 子类数量按维度相乘增长。
  • 父类修改可能影响大量子类。
  • 相同实现逻辑容易散落在多个组合类。
  • 运行时切换实现方式很麻烦。
  • 类层级过深后理解成本上升。

例如 PdfFinanceReport 如果继承了 FinanceReport,那它既承载财务口径,又承载 PDF 输出。以后要把同一份财务报表导出 Excel,就要再写一个 ExcelFinanceReport

三、桥接方案如何改善

桥接方案会把报表口径和导出格式拆开:

abstract class Report {
    protected final Exporter exporter;

    protected Report(Exporter exporter) {
        this.exporter = exporter;
    }

    public abstract void export();
}

报表类负责准备数据,导出器负责输出格式。两边职责清楚,扩展也分开。

四、组合带来的运行时灵活性

继承是在编译期固定类型层级,组合是在对象创建时建立关系。

这意味着桥接模式可以运行时决定使用哪种实现:

Exporter exporter = userChoosePdf ? new PdfExporter() : new ExcelExporter();
Report report = new FinanceReport(exporter);
report.export();

如果用继承,就要提前选择 PdfFinanceReportExcelFinanceReport,并且相关逻辑更容易散在不同类中。

五、桥接不是完全替代继承

桥接模式内部仍然可以使用继承。抽象侧可能有父类和子类,实现侧也可能有接口和多个实现类。

它反对的不是继承本身,而是用一条继承链同时表达多个变化维度。

更准确地说,桥接模式是把继承从“组合维度”中解放出来,让每个维度内部各自组织层次。

六、什么时候继承更简单

如果需求非常稳定,并且只有少量固定类型,用桥接可能没有必要。

例如一个小工具只有 PdfReportExcelReport 两个类,没有报表类型扩展,也没有运行时组合需求,直接写两个类更清楚。

设计模式要看变化趋势。如果变化维度不成立,桥接会增加额外抽象。

七、常见误区与追问

继承方案把两个维度固化在类层次中,桥接则把其中一维变成对象组合。3种形状配4种渲染器若交叉继承,理论上要12个组合子类;桥接只需3个形状类加4个渲染实现,共7个核心类型。数量优势之外,运行期替换实现也是继承难以提供的。

检查维度判定依据
交叉继承组合数量约为 A × B
桥接拆分核心类型数量约为 A + B
3 × 4 = 12;桥接后 3 + 4 = 7

记忆钩子:继承把选择写进类型,桥接把选择放进对象装配。

  • 误区:继承永远不如桥接。 单一稳定维度且共享实现明确时,继承更直接。
  • 追问:桥接如何避免类爆炸? 两个维度分别扩展,通过运行期组合形成搭配,不为每个搭配建子类。
  • 误区:桥接会消除所有组合数量。 运行期组合仍有 A×B 种,只是不需要 A×B 个类。
  • 追问:何时从继承重构为桥接? 第二个变化维度出现、子类命名交叉且修改传播时。
  • 追问:组合的代价是什么? 多一次对象间委托,并需要明确装配与生命周期管理。

八、加强记忆

桥接和继承的区别可以记成:继承把组合写死在类名里,桥接把组合放到对象关系里。前者适合稳定层级,后者适合多维度变化。