装饰者模式
定义:
动态的给一个对象添加功能,比单纯的子类继承更灵活
设计初衷:
通常可以使用继承来实现功能的拓展,如果这些需要拓展的功能的种类很繁多,那么势必生成很多子类,增加系统的复杂性,同时,使用继承实现功能拓展,我们必须可预见这些拓展功能,这些功能是编译时就确定了,是静态的。
重点:
装饰者和被装饰者有共同的超类,继承的目的是继承类型,不是具体的行为和功能
1. 煎饼基类: 被装饰者(Component)
/**
* @author XQ0136
* @description 煎饼
* @date 2022/7/30 16:17
*/
public abstract class Pancake {
protected abstract double getPrice();
}
2. 原味煎饼:具体的主体(ConcreteComponent )
/**
* @author XQ0136
* @description 原味煎饼
* @date 2022/7/30 16:17
*/
public class PlainPancake extends Pancake {
@Override
protected double getPrice() {
return 0;
}
}
3. 配料:装饰者(Decorator)
/**
* @author XQ0136
* @description 配料
* @date 2022/7/30 16:51
*/
public abstract class Condiment extends PlainPancake{
}
/**
* @author XQ0136
* @description 辣椒
* @date 2022/7/30 16:41
*/
public class Chili extends Condiment{
PlainPancake plainPancake;
Chili(PlainPancake plainPancake){
this.plainPancake = plainPancake;
}
@Override
protected double getPrice() {
System.out.println("加辣椒!");
return plainPancake.getPrice() +1.0;
}
}
/**
* @author XQ0136
* @description 火腿
* @date 2022/7/30 16:41
*/
public class Ham extends Condiment{
PlainPancake plainPancake;
Ham(PlainPancake plainPancake){
this.plainPancake = plainPancake;
}
@Override
protected double getPrice() {
System.out.println("加火腿!");
return plainPancake.getPrice() +2.0;
}
}
/**
* @author XQ0136
* @description 生菜
* @date 2022/7/30 16:41
*/
public class Lettuce extends Condiment{
PlainPancake plainPancake;
Lettuce(PlainPancake plainPancake){
this.plainPancake = plainPancake;
}
@Override
protected double getPrice() {
System.out.println("加生菜!");
return plainPancake.getPrice() +10.0;
}
}
4. 测试运行
/**
* @author XQ0136
* @description
* @date 2022/7/30 17:02
*/
public class Testmain {
public static void main(String[] args) {
//先煎个饼
PlainPancake plainPancake = new PlainPancake();
//加生菜 加生菜 加辣椒 加火腿
Condiment condiment = new Lettuce(new Lettuce(new Chili(new Ham(plainPancake))));
double price = condiment.getPrice();
System.out.println(price);
}
}
运行结果:
装饰者模式优点:
动态的将新功能附加到对象上。在对象功能拓展方面,它比继承更有弹性。由上面的例子来说:对象就指煎饼,附加的功能就是各种配料,将调料(功能)和煎饼(对象)分开,这样拓展性更高,而不是指定原味煎饼就只能是原味的,火腿煎饼就只能是加火腿的,不能添加其他配料
装饰者模式缺点:
- 机动性变高意味着增加了更多的复杂性,如果多层装饰中有了问题,需要一层一层的查找,复杂性可想而知
- 设计中会导致出现许多小类,如果过度使用,也会使程序更复杂