定义: 例如: 一个快餐店当中有炒饭和炒面, 炒饭和炒面又分为鸡蛋炒饭/面和培根炒饭/面, 一般写法是, 定义一个快餐类然后创建一个炒饭/面类继承快餐类, 再创建鸡蛋/培根 炒饭/面类继承炒饭/面类, 这样会让系统变得臃肿而且不灵活, 每次新增快餐都要创建很多类. 装饰器模式可以在不改变现有的结构模式下, 动态的给对象增加一些职责.
结构:
- 抽象构件: 一个抽象接口, 用于规范准备接收附加责任的对象
- 具体构件: 实现抽象构件, 通过装饰为角色添加一些职责
- 抽象装饰: 继承或实现抽象构件, 并且包含具体构件的实例, 可以通过子类扩展具体构件的功能
- 具体装饰: 实现抽象装饰的相关方法, 并给具体构件对象添加附加责任
实现:
例: 一个快餐店当中有炒饭和炒面, 炒饭和炒面又分为鸡蛋炒饭/面和培根炒饭/面
抽象构件
@Data
@AllArgsConstructor
@NoArgsConstructor
public abstract class FastFood {
private double price;
private String desc;
public abstract double cost();
}
具体构件
public class FriedNoodles extends FastFood {
public FriedNoodles() {
super(15, "炒面");
}
public double cost() {
return getPrice();
}
}
public class FriedRice extends FastFood {
public FriedRice() {
super(10, "炒饭");
}
public double cost() {
return getPrice();
}
}
- 1
- 2
- 3
- 4
- 5
- 6
- 7
- 8
- 9
- 10
- 11
- 12
- 13
- 14
- 15
- 16
- 17
- 18
- 19
- 20
- 21
- 22
- 23
- 24
- 25
- 26
- 27
抽象装饰
@Data
public abstract class Garnish extends FastFood {
private FastFood fastFood;
public Garnish(FastFood fastFood, double price, String desc) {
super(price, desc);
this.fastFood = fastFood;
}
}
具体装饰
public class Egg extends Garnish {
public Egg(FastFood fastFood) {
super(fastFood, 2, "鸡蛋");
}
public double cost() {
return getPrice() + getFastFood().cost();
}
@Override
public String getDesc() {
return super.getDesc() + getFastFood().getDesc();
}
}
public class Bacon extends Garnish {
public Bacon(FastFood fastFood) {
super(fastFood, 4, "培根");
}
public double cost() {
return getPrice() + getFastFood().cost();
}
@Override
public String getDesc() {
return super.getDesc() + getFastFood().getDesc();
}
}
- 1
- 2
- 3
- 4
- 5
- 6
- 7
- 8
- 9
- 10
- 11
- 12
- 13
- 14
- 15
- 16
- 17
- 18
- 19
- 20
- 21
- 22
- 23
- 24
- 25
- 26
- 27
- 28
- 29
- 30
- 31
- 32
- 33
- 34
- 35
- 36
- 37
- 38
Main
public class Main {
public static void main(String[] args) {
FastFood friedRice = new FriedRice();
System.out.println(friedRice.getDesc() + ": " + friedRice.cost());
FastFood eggFriedRice = new Egg(friedRice);
System.out.println(eggFriedRice.getDesc() + ": " + eggFriedRice.cost());
FastFood baconEggFriedRice = new Bacon(eggFriedRice);
System.out.println(baconEggFriedRice.getDesc() + ": " + baconEggFriedRice.cost());
}
}
- 1
- 2
- 3
- 4
- 5
- 6
- 7
- 8
- 9
- 10
- 11
- 12
- 13
- 14
- 15
- 16
- 17
- 18
- 19
- 20
- 21
- 22
使用场景:
- 当不能采用继承方式对系统进行扩充或者采用继承不利于维护时
不能采用继承方式的情况
- 第一类是系统中存在大量独立的扩展, 为支持每一种组合产生大量的子类
- 第二类是因为类定义不能继承
- 在不影响其他对象的情况下, 动态透明的给单个对象添加职责
- 当对象的功能要求可以动态添加, 也可以动态撤销时