桥接模式和适配器、策略、外观模式有什么区别?
简化版
桥接模式关注两个变化维度的长期解耦;适配器模式关注兼容已有接口;策略模式关注算法或行为的可替换;外观模式关注为复杂子系统提供统一入口。它们都可能用组合,但设计动机不同。
详细版
几个模式的区别可以从目的看:
- 桥接模式:提前设计两个可独立扩展的维度,避免类爆炸。
- 适配器模式:已有接口不匹配,通过适配层让它能接入目标接口。
- 策略模式:把一组可替换算法封装起来,运行时选择一种。
- 外观模式:封装复杂子系统,给客户端一个简单入口。
桥接更像架构拆维度;适配器更像接口补丁;策略更像行为替换;外观更像门面简化。
完整版教学
一、桥接模式和适配器模式
桥接模式通常是在设计早期使用,用来拆分抽象和实现两个维度。它强调两个维度都能扩展。
适配器模式通常是在系统已有之后使用,用来解决接口不兼容问题。例如第三方 SDK 的方法名、参数结构和系统内部接口不一致,就写一个适配器转接。
对比:
| 对比点 | 桥接模式 | 适配器模式 |
|---|---|---|
| 主要目的 | 分离两个变化维度 | 兼容不匹配接口 |
| 使用时机 | 多在设计阶段 | 多在集成或重构阶段 |
| 关注点 | 扩展性和解耦 | 接口转换 |
| 典型关系 | 抽象持有实现接口 | 适配器包装被适配对象 |
如果面试官问“桥接和适配器都像在中间加一层,有什么区别”,可以答:桥接是为了未来扩展主动拆维度,适配器是为了接入已有对象被动做兼容。
二、桥接模式和策略模式
策略模式把一组算法封装成策略接口,让上下文对象可以切换策略。它通常只有一个主要变化点:算法或行为。
桥接模式强调两个独立变化维度。抽象侧本身也可能有继承扩展,实现侧也可能有多个实现。
例如消息发送:
- 如果只是选择短信还是邮件发送,可以看作策略。
- 如果同时存在普通消息、紧急消息、验证码消息,并且它们都要支持多种渠道,就更适合桥接。
对比:
| 对比点 | 桥接模式 | 策略模式 |
|---|---|---|
| 变化维度 | 通常两个维度 | 通常一个行为维度 |
| 抽象侧 | 本身可扩展 | 多数是上下文类 |
| 目标 | 避免维度组合爆炸 | 替换算法和消除条件分支 |
| 示例 | 消息类型 × 发送渠道 | 价格计算策略、排序策略 |
策略模式可以看作桥接模式中的实现侧,但桥接的结构更强调抽象侧也在变化。
三、桥接模式和外观模式
外观模式给复杂子系统提供一个统一入口,让客户端不用直接面对多个子系统对象。
桥接模式不是为了简化调用入口,而是为了拆分变化维度。
例如:
PaymentFacade.pay()内部协调订单、库存、风控、支付,这是外观。Payment持有PaymentChannel,让支付业务和支付通道独立扩展,这是桥接。
外观模式的客户端通常只看到一个简单门面;桥接模式的客户端或装配层通常要选择并组合抽象和实现。
四、为什么它们容易混淆
这些模式都大量使用组合和接口:
- 桥接:抽象对象组合实现接口。
- 适配器:适配器组合被适配对象。
- 策略:上下文组合策略接口。
- 外观:门面组合多个子系统对象。
所以不能只看代码结构判断模式,要看设计意图。设计模式最重要的是“为什么这样设计”,而不是“有没有接口和组合”。
五、面试回答模板
可以这样答:
桥接模式是为了解决抽象和实现两个维度独立变化的问题;适配器是解决已有接口不兼容;策略是解决一组算法或行为可替换;外观是隐藏子系统复杂性。它们代码上都可能表现为组合,但桥接的关键词是双维度扩展和避免类爆炸。
这个回答清楚地区分了目的、时机和场景。
六、常见误区与追问
四种模式都可能表现为持有接口,但意图和时机不同。桥接在设计期拆开2个变化维度;适配器通常在接口已不兼容时转换;策略替换1组算法;外观为复杂子系统提供更简单入口。不能用“是否组合”判断,因为四者都可能使用组合。
| 检查维度 | 判定依据 |
|---|---|
| 桥接 / 适配器 | 分离维度 / 转换接口 |
| 策略 / 外观 | 替换算法 / 简化入口 |
桥接=A↔B;适配=新接口->旧接口;外观=1->N
记忆钩子:桥接管维度,适配器管兼容,策略管算法,外观管入口。
- 误区:桥接就是提前写好的适配器。 桥接两侧共同演化,适配器主要弥合既有接口差异。
- 追问:桥接中的 Implementor 算策略吗? 若它仅代表可替换算法可视为策略;若是一条长期实现维度,桥接解释更准确。
- 误区:外观也拆分两个维度。 外观重点是减少客户端接触的子系统接口数量。
- 追问:同一设计能组合这些模式吗? 可以,例如 Abstraction 通过适配器连接旧平台实现。
- 追问:面试如何快速作答? 先说各自解决的问题,再对比结构关系和引入时机。
七、加强记忆
区分这几个模式时先看动机:桥接拆维度,适配器接旧口,策略换算法,外观包复杂。代码结构相似时,设计动机才是判断依据。