1. 定义
动态地将责任附加到对象上,在扩展功能时,该模式提供了比继承更有弹性的替代方案。
2. 角色
- Component:抽象构件
- ConcreteComponent:具体构件
- Decorator:抽象装饰类,是抽象构件的子类,内部持有对Component实例的一个引用
- ConcreteDecorator:具体装饰类
3. 特点
- 优点:用该模式来实现扩展比使用继承灵活,有较好的松耦合性,可以对用户以透明的方式动态地给对象附加更多的责任。
- 缺点:该模式会产生许多小对象,出错时排错比较繁琐,需要逐级排查。
4. 示例
Drink:
public abstract class Drink {
String name;
public String getName() {
return name;
}
public abstract int cost();
}
Condiment:
public abstract class Condiment extends Drink {
public abstract String getName();
// 因为所有调料都要重新实现该方法,因此将该方法改为抽象方法
}
MilkTea:
public class MilkTea extends Drink {
public MilkTea() {
name = "奶茶";
}
@Override
public int cost() {
return 20;
}
}
具体调料实现类:
// ZhenZhu
public class ZhenZhu extends Condiment {
Drink drink;
public ZhenZhu(Drink drink) {
this.drink = drink;
}
public String getName() {
return drink.getName() + "珍珠";
}
@Override
public int cost() {
return drink.cost() + 3;
}
}
// NaiGai
public class NaiGai extends Condiment {
Drink drink;
public NaiGai(Drink drink) {
this.drink = drink;
}
public String getName() {
return drink.getName() + "奶盖";
}
@Override
public int cost() {
return drink.cost() + 4;
}
}
测试类:
public class TestDecorator {
public static void main(String[] args) {
Drink drink = new NaiGai(new ZhenZhu(new MilkTea()));
System.out.println(drink.getName());
System.out.println(drink.cost());
}
}
// 输出
// 奶茶珍珠奶盖
// 27
参考:
1. 《Head First 设计模式》
2. 《图说设计模式》 https://design-patterns.readthedocs.io/zh_CN/latest/structural_patterns/decorator.html