装饰器模式通过组合在运行时动态添加职责,不修改原类结构;核心是用实现同一接口的包装类持有被装饰对象,在方法调用前后插入逻辑,支持多层叠加且符合开闭原则。

装饰器模式通过组合而非继承,在运行时动态地为对象添加新职责,不改变原有类结构,也不影响其他对象。
核心思路:用包装类增强功能
装饰器本质是一个“包装器”——它持有一个被装饰对象的引用,并在调用其方法前后插入额外逻辑。所有装饰器和被装饰对象实现同一接口(或继承同一抽象类),保证客户端无感知。
- 定义统一组件接口(如 Component)
- 具体实现类(ConcreteComponent)提供基础行为
- 装饰器基类(Decorator)也实现该接口,并持有 Component 引用
- 具体装饰器(如 LoggingDecorator、CacheDecorator)继承装饰器基类,在方法中扩展逻辑
代码示例:给文本处理器加日志和加密
假设有个 TextProcessor 接口:
interface TextProcessor {
String process(String text);
}
基础实现:
立即学习“Java免费学习笔记(深入)”;
Java项目代码review工具。分析Git变更+完整调用链路上下文,推断业务需求,进行多维度评分和分类汇总,生成完整PRD文档。包含细粒度Java代码审查清单(Null安全、异常处理、Streams、并发、equals/hashCode、资源管理、API设计、性能、MyBatis/ORM、事务边界、SQL/DD...
class SimpleProcessor implements TextProcessor {
public String process(String text) {
return "processed: " + text;
}
}
装饰器基类:
abstract class TextProcessorDecorator implements TextProcessor {
protected final TextProcessor wrapped;
TextProcessorDecorator(TextProcessor wrapped) {
this.wrapped = wrapped;
}
}
具体装饰器(日志):
class LoggingDecorator extends TextProcessorDecorator {
LoggingDecorator(TextProcessor wrapped) {
super(wrapped);
}
public String process(String text) {
System.out.println("→ Logging: processing '" + text + "'");
return wrapped.process(text);
}
}
另一个装饰器(大小写反转):
class UppercaseDecorator extends TextProcessorDecorator {
UppercaseDecorator(TextProcessor wrapped) {
super(wrapped);
}
public String process(String text) {
return wrapped.process(text).toUpperCase();
}
}
动态组合使用:
TextProcessor processor = new SimpleProcessor();
processor = new LoggingDecorator(processor); // 加日志
processor = new UppercaseDecorator(processor); // 再加大写
String result = processor.process("hello"); // 输出:PROCESSED: HELLO,并打印日志
关键要点与注意事项
- 装饰器必须和被装饰对象类型兼容:靠接口/抽象类统一契约,否则无法链式调用
- 构造时传入被装饰对象:这是“动态”的来源——实例化时决定加哪些层,而非编译期固定
- 可叠加多个装饰器:顺序影响结果(如先日志后加密,和先加密后日志行为不同)
- 避免过度嵌套:层数太多会增加调试难度,必要时可考虑构建器或工厂封装创建逻辑
- Java I/O 类库是经典应用:如 BufferedInputStream 包装 FileInputStream,就是装饰器的实际体现
对比继承:为什么更灵活?
如果用继承扩展职责,每种组合都要一个子类(如 LoggedSimpleProcessor、CachedSimpleProcessor、LoggedCachedSimpleProcessor……),组合爆炸。而装饰器只需写 LoggingDecorator 和 CachingDecorator,就能任意组合,新增职责无需修改已有代码,符合开闭原则。

















