概述
定义:在不改变原有对象的基础之上,将功能附加到对象上
优点:提供了比继承更有弹性的替代方案;通过使用不同装饰类以及这些装饰类的排列组合,可以实现不同效果。
缺点:出现更多代码,更多的类,增加程序复杂性。
类型:结构型
装饰者模式角色:
- Component:装饰者和被装饰者共同的父类
- ConcreteComponent:定义具体对象,即被装饰者
- Decorator:抽象装饰者,继承自Componet,从外类来扩展ConcreteComponet;对于ConcreteComponent来说,不需要知道Decorator的存在;装饰者和被装饰者具有相同的超类型,这里利用继承是为了达到类型匹配,而不是利用继承获取行为。通过注入被装饰者对象,起到对被装饰者进行加强的效果
- ConcreteDecorator:具体装饰者,用于扩展ConcreteComponent
小栗子
假设一家煎饼店,卖煎饼,除了煎饼本身还可以加鸡蛋,加热狗,但是这些需要另外收费,我们通过装饰者设计模式实现动态扩展。
#Componet
public abstract class AbstractBatterCake {
public abstract String description();
public abstract int cost();
}
#ConcreteComponent
public class batterCake extends AbstractBatterCake {
@Override
public String description() {
return "这是一张煎饼底子";
}
@Override
public int cost() {
return 8;
}
}
public abstract class AbstractDecorator extends AbstractBatterCake {
//无实现
}
#ConcreteDecorator
public class eggDecorator extends AbstractDecorator {
private AbstractBatterCake cake;
public eggDecorator(AbstractBatterCake cake){
this.cake=cake;
}
@Override
public int cost() {
return this.cake.cost()+3;
}
@Override
public String description() {
return this.cake.description()+"加一个鸡蛋";
}
}
public class hotdogDecorator extends AbstracDecorator {
private AbstractBatterCake cake;
public hotdogDecorator(AbstractBatterCake cake){
this.cake=cake;
}
@Override
public int cost() {
return this.cake.cost()+4;
}
@Override
public String description() {
return this.cake.description()+"加一条热狗";
}
}
#测试类
public static void main(String[] args) {
batterCake batterCake = new batterCake();
//注入需要被装饰的对象
eggDecorator battercake1 = new eggDecorator(batterCake);
hotdogDecorator battercake2 = new hotdogDecorator(battercake1);
System.out.println(battercake2.description()+battercake2.cost());
//这是一张煎饼底子加一个鸡蛋加一条热狗15
}