结构型模式的选型难点
结构型模式在评审中经常被混淆,原因是它们的类图看起来相似:都涉及一个类持有另一个类并转发调用。区别在意图——适配器转换接口,桥接拆分维度,装饰器叠加行为,外观简化入口,代理控制访问。选型时先明确要解决的问题,再看哪个模式的意图与之匹配,而不是看结构像哪个。
结构型模式对照
| 模式 | 意图 | 典型信号 |
|---|---|---|
| Adapter | 把接口转换成调用方期望的形态 | 第三方接口与本地约定不兼容 |
| Bridge | 抽象与实现解耦,两个维度独立扩展 | 子类数量呈相乘关系 |
| Decorator | 在同一接口上叠加行为 | 多层可选增强,任意组合 |
| Facade | 为复杂子系统提供统一简化入口 | 调用方需要依次协调多个组件 |
| Proxy | 控制对目标对象的访问 | 需要延迟加载、权限校验或远程调用 |
| Composite | 把单个对象与组合对象统一对待 | 树形结构需要统一处理 |
典型使用场景
- 接入第三方支付:用适配器把对方接口转成本地统一约定,隔离外部变化
- 报表输出增强:加缓存、加权限过滤、加日志,用装饰器按需叠加而不是为组合派生类
- 老系统对外提供简化入口:用外观把多个内部调用收拢成一个方法
- 大对象延迟加载:用代理在首次访问时才真正创建目标
- 组织结构与文件目录:用组合统一处理单个与容器节点
一句话辅助记忆
一句话辅助记忆
# 目的是区分意图,不是记结构
Adapter 是翻译官:把一种接口说成另一种
Bridge 是立交桥:两条路各走各的,互不干扰
Decorator 是穿外套:外套相同,可以叠穿
Facade 是前台:一句话办完内部一堆事
Proxy 是门卫:先问来意,再决定放不放行选型三步
| 第一步 | 用一句话写出当前问题,不带模式名 |
|---|---|
| 第二步 | 确定变化点:接口不兼容、维度扩展、行为叠加、访问控制 |
| 第三步 | 对照意图表选择,若两个都符合则先做更小改动 |
代理与装饰器在结构上几乎一样,区别在职责归属:装饰器明确要在原行为之外增加功能,代理则是替目标挡在前面处理访问控制,功能本身不增加。评审时问一句「这个类有没有改变原有语义」,能较快区分。
外观不禁止直接访问子系统:它提供的是常用路径的简化入口。若强制所有调用都经过外观,子系统会失去灵活性,外观也会膨胀成新的上帝类。
落地检查清单
- 模式选择能对应到一句话问题描述
- 新增一个实现或增强时,改动范围局限在预期处
- 调用链层次清晰,不出现多层同类包装互相嵌套
- 接口命名反映意图,而不是模式名