装饰器模式通过组合动态扩展对象行为,核心是装饰器持有被装饰对象引用并委托调用;需定义统一接口,抽象装饰器提供默认委托实现,具体装饰器只添加自身逻辑,使用时可自由叠加。

在 Java 中,装饰器模式通过对象组合而非继承来动态扩展对象行为,核心是让装饰器类持有被装饰对象的引用,并在其方法调用前后添加新逻辑。它比继承更灵活,避免类爆炸,且符合开闭原则。
定义统一接口或抽象组件
所有具体组件和装饰器都实现同一接口(或继承同一抽象类),确保可替换性与多态调用:
interface Coffee {
String getDescription();
double getCost();
}
例如,基础咖啡实现:
class SimpleCoffee implements Coffee {
public String getDescription() { return "Simple coffee"; }
public double getCost() { return 2.0; }
}
创建装饰器基类(可选但推荐)
抽象装饰器持有组件引用,实现接口,并将默认行为委托给被装饰对象,便于复用:
分析 Java Spring Boot 后端 Controller 代码,自动生成 Markdown 格式的接口文档。当用户说“生成 Java 接口文档”、“生成 API 文档”、“从 Spring 代码生成文档”时触发。
abstract class CoffeeDecorator implements Coffee {
protected final Coffee coffee;
protected CoffeeDecorator(Coffee coffee) {
this.coffee = coffee;
}
@Override
public String getDescription() {
return coffee.getDescription();
}
@Override
public double getCost() {
return coffee.getCost();
}
}
编写具体装饰器,按需叠加功能
每个装饰器只关注自身增强逻辑,在委托前后插入行为。例如添加牛奶、焦糖等配料:
class MilkDecorator extends CoffeeDecorator {
MilkDecorator(Coffee coffee) {
super(coffee);
}
@Override
public String getDescription() {
return coffee.getDescription() + ", milk";
}
@Override
public double getCost() {
return coffee.getCost() + 0.5;
}
}
class CaramelDecorator extends CoffeeDecorator {
CaramelDecorator(Coffee coffee) {
super(coffee);
}
@Override
public String getDescription() {
return coffee.getDescription() + ", caramel";
}
@Override
public double getCost() {
return coffee.getCost() + 0.7;
}
}
使用时自由组合:
Coffee order = new SimpleCoffee(); order = new MilkDecorator(order); order = new CaramelDecorator(order); System.out.println(order.getDescription()); // Simple coffee, milk, caramel System.out.println(order.getCost()); // 3.2
关键设计要点
- 装饰器必须与被装饰对象类型兼容:通过共同接口/父类保证,运行时可任意嵌套
- 构造时传入被装饰对象:体现“组合”关系,而非继承;生命周期由客户端控制
-
避免循环依赖或无限委托:装饰器内部只调用
coffee.xxx(),不反向调用自身 -
可配合工厂或构建器简化复杂装饰链:例如
CoffeeBuilder.withMilk().withCaramel().build()
不复杂但容易忽略。
Java免费学习笔记:立即使用
解锁 Java 大师之旅:从入门到精通的终极指南










