首页/开发/代码质量与评审速查/装饰器模式 Decorator(结构型)
设计原则与模式62 条

装饰器模式 Decorator(结构型)

在不改变接口的前提下为对象叠加行为:层层包装(如流处理、压缩、加密、缓存)可自由组合;相比继承,组合方式在运行期决定。

装饰器模式是什么

装饰器在不改变接口的前提下为对象叠加行为:层层包装,每层只做一件事,例如缓冲、压缩、加密、缓存。相比继承,叠加方式在运行期决定,组合数量不受类层次限制。判断是否适用,看这层职责是否需要在不同组合下复用。

基本信息

意图动态叠加职责,接口保持不变
形态实现同一接口,内部持有被装饰对象
典型实例输入输出流管道、HTTP 中间件链
关键性质包装顺序即执行顺序
与代理的区别装饰器关注叠加职责,代理关注访问控制

典型使用场景

  • 流处理叠加缓冲、压缩与加密
  • HTTP 中间件链添加鉴权、日志与限流
  • 缓存层包裹数据访问对象
  • 指标采集包裹调用入口
  • 按配置组合横切能力

Java 流管道

Java 流管道
InputStream in = new BufferedInputStream(
    new GZIPInputStream(
        new FileInputStream(path)));

// 读取顺序:先解压,再经过缓冲层
// 包装顺序反过来写,行为与性能都会不同

与相邻模式的差别

模式目的差别
装饰器叠加职责接口不变,可多层包装
代理控制访问通常一对一,关注权限或延迟加载
适配器转换接口改变对外的接口形状
中间件与装饰链的执行顺序就是包装顺序:排查问题时先确认层序,再看每层做了什么,通常比逐层加日志更快。

落地要点

  • 每层只做一件事,职责单一时才好自由组合
  • 对外接口保持一致,调用方无需知道包装了几层
  • 组合顺序配置化,并在文档或注释里写清实际顺序
  • 为关键层加指标,便于定位是哪一层拖慢了调用
  • 固定搭配的几层可以合并成语义明确的组件
层数过多会让一次调用穿过十几层:调试时栈很深、性能也有开销。固定搭配的层可以合并,组合方式要保持可读。
测试装饰链时优先测组合后的行为:既验证每层自身,也验证顺序正确,例如先压缩后加密与先加密后压缩的结果完全不同。

易错点

  • 层数过多:一次调用穿过十几层,调试与性能都受损
  • 装饰器假设被包装对象的身份:与代理语义混淆,换了包装层就出错
  • 包装顺序写反:数据流向与预期不符,表现为格式错误而不是异常
  • 每层都做参数校验与转换:职责重复,出错时难以定位是哪一层处理的

数据来源与参考

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