结构型-装饰器模式
2026/1/15大约 2 分钟Java设计模式结构型模式装饰器模式Java设计模式面向对象架构设计最佳实践代码优化
概述
装饰器模式(Decorator Pattern)动态地给一个对象添加一些额外的职责。就增加功能来说,装饰器模式相比生成子类更为灵活。
适用场景
- 在不影响其他对象的情况下,以动态、透明的方式给单个对象添加职责
- 需要动态地给一个对象增加功能,这些功能也可以动态地被撤销
- 当不能采用继承的方式对系统进行扩充或者采用继承不利于系统扩展和维护时
角色组成
- Component(抽象构件):定义对象接口
- ConcreteComponent(具体构件):定义具体对象
- Decorator(抽象装饰类):持有Component引用,实现Component接口
- ConcreteDecorator(具体装饰类):负责给构件添加新的职责
代码实现
1. 抽象构件
public interface Coffee {
String getDescription();
double getCost();
}2. 具体构件
public class SimpleCoffee implements Coffee {
@Override
public String getDescription() {
return "简单咖啡";
}
@Override
public double getCost() {
return 10.0;
}
}3. 抽象装饰类
public abstract class CoffeeDecorator implements Coffee {
protected Coffee coffee;
public CoffeeDecorator(Coffee coffee) {
this.coffee = coffee;
}
@Override
public String getDescription() {
return coffee.getDescription();
}
@Override
public double getCost() {
return coffee.getCost();
}
}4. 具体装饰类
// 加牛奶
public class MilkDecorator extends CoffeeDecorator {
public MilkDecorator(Coffee coffee) {
super(coffee);
}
@Override
public String getDescription() {
return coffee.getDescription() + " + 牛奶";
}
@Override
public double getCost() {
return coffee.getCost() + 3.0;
}
}
// 加糖
public class SugarDecorator extends CoffeeDecorator {
public SugarDecorator(Coffee coffee) {
super(coffee);
}
@Override
public String getDescription() {
return coffee.getDescription() + " + 糖";
}
@Override
public double getCost() {
return coffee.getCost() + 1.0;
}
}5. 客户端
public class Client {
public static void main(String[] args) {
Coffee coffee = new SimpleCoffee();
System.out.println(coffee.getDescription() + " ¥" + coffee.getCost());
// 加牛奶
coffee = new MilkDecorator(coffee);
System.out.println(coffee.getDescription() + " ¥" + coffee.getCost());
// 再加糖
coffee = new SugarDecorator(coffee);
System.out.println(coffee.getDescription() + " ¥" + coffee.getCost());
}
}# 输出
简单咖啡 ¥10.0
简单咖啡 + 牛奶 ¥13.0
简单咖啡 + 牛奶 + 糖 ¥14.0类图
JDK 中的应用
java.io.BufferedInputStreamjava.io.BufferedOutputStreamjava.io.BufferedReaderjava.util.Collections#synchronizedList()
// IO 流装饰器示例
InputStream is = new FileInputStream("file.txt");
InputStream bis = new BufferedInputStream(is);
InputStream dis = new DataInputStream(bis);优缺点
优点:
- 装饰类和被装饰类可以独立发展
- 装饰模式是继承的一个替代模式
- 可以动态扩展一个实现类的功能
缺点:
- 多层装饰比较复杂
- 会产生很多小对象
装饰器 vs 继承
| 特性 | 装饰器模式 | 继承 |
|---|---|---|
| 扩展方式 | 动态 | 静态 |
| 灵活性 | 高 | 低 |
| 类数量 | 较少 | 可能爆炸 |
| 组合方式 | 任意组合 | 固定 |
