装饰器模式通过组合与接口多态实现动态功能扩展,避免继承导致的类爆炸;核心是装饰器持有被装饰对象引用并委托调用,在方法前后插入逻辑,支持运行时任意叠加。

装饰器模式在Java中不依赖继承来扩展功能,而是通过组合与接口多态实现动态增强——它刻意避免子类膨胀,用“包装”代替“继承”。
核心思路:用接口统一行为,用组合添加责任
装饰器模式要求被装饰对象和装饰器都实现同一个接口(或抽象类)。装饰器内部持有一个该接口的引用,在调用方法时可以前置/后置处理,再委托给被装饰对象。这种设计让扩展行为变成运行时的“层层包裹”,而非编译期的类继承关系。
- 被装饰类(如
ConcreteComponent)直接实现接口,提供基础功能 - 装饰器基类(
Decorator)也实现同一接口,并持有接口类型的成员变量 - 具体装饰器(如
LoggingDecorator、CacheDecorator)继承基类装饰器,重写方法,在调用super.method()前后插入逻辑
为什么不是靠继承扩展功能?
继承(extends)在Java中是静态的、单向的、编译期绑定的。而装饰器模式要的是运行时可选、可叠加、可拆卸的能力。比如一个数据处理器,可能需要日志+缓存+权限校验,三者任意组合。如果靠继承,就得写 2³=8 个子类(LoggingProcessor、CacheProcessor、LoggingCacheProcessor……),违背开闭原则。
Java JDK 25 来自 OpenJDK 官方归档,版本为 JDK 25,本条下载地址已指向官方 Windows x64 zip 安装包直链,适合调试旧项目或兼容旧版 Java 运行环境。
装饰器则只需三个独立类:LoggingDecorator、CacheDecorator、AuthDecorator,然后这样组合:
new LoggingDecorator(
new CacheDecorator(
new AuthDecorator(
new DataProcessor()
)
)
)
多态如何支撑动态性?
所有组件(原始对象 + 各种装饰器)都声明为接口类型,调用方只面向接口编程:
- 方法参数、变量、返回值都使用接口(如
Processor) - 运行时实际指向哪个具体对象(纯实现 or 某层装饰器)由构造过程决定
- JVM通过虚方法表动态分派,自动调用对应实例的重写方法
这意味着同一段业务代码(如 processor.handle(request))无需修改,就能因传入不同包装链而表现出日志、缓存、熔断等不同行为。
关键编码要点
- 定义清晰的功能接口(如
DataSource),所有扩展必须围绕它展开 - 装饰器基类构造器强制接收该接口类型参数,确保组合关系明确
- 每个具体装饰器只关注自己那一层职责,不感知外层或内层细节
- 避免装饰器之间互相依赖,保持正交性
Java免费学习笔记:立即使用
解锁 Java 大师之旅:从入门到精通的终极指南










