作用
在不改变原有对象的基础上,将功能附加到对象上
提供比继承更有的弹性替代方案,扩展原有对象功能
动态的给对象添加功能,并动态的撤销
是继承的有力补充
Demo设计
假设有一个煎饼,可以加鸡蛋,火腿等,在不改变煎饼类的情况下对煎饼对象加更多的料
定义一个接口
显示煎饼的信息和价格
public interface BatterCake {
String getDesc();
int cost();
}
被装饰的对象
实现接口,表示为原味煎饼,什么料都不加
public class BatterCakeNormal implements BatterCake {
@Override
public String getDesc() {
return "煎饼";
}
@Override
public int cost() {
return 6;
}
}
装饰者抽象类
由于可以使用多个装饰者对对象进行修饰,所以需要先创建一个抽象类,要实现接口
为什么要使用抽象类呢,可以用于子类在装饰的时候必须要做一个操作
public abstract class BaseDecorator implements BatterCake {
/**
* 用来注入
*/
private final BatterCake batterCake;
public BaseDecorator(BatterCake batterCake) {
this.batterCake = batterCake;
}
protected abstract void doSomething();
@Override
public String getDesc() {
return this.batterCake.getDesc();
}
@Override
public int cost() {
return this.batterCake.cost();
}
}
装饰者类
比如煎饼可以加鸡蛋,创建一个鸡蛋装饰者类,继承装饰者父类,重写父类的有参构造方法
public class EggDecorator extends BaseDecorator {
public EggDecorator(BatterCake batterCake) {
super(batterCake);
}
@Override
public String getDesc() {
return super.getDesc() + "再加一个蛋";
}
@Override
public int cost() {
return super.cost() + 1;
}
}
比如煎饼可以加火腿,再写一个火腿装饰者类
public class SausageDecorator extends BaseDecorator {
public SausageDecorator(BatterCake batterCake) {
super(batterCake);
}
@Override
public String getDesc() {
return super.getDesc() + "再加一根火腿";
}
@Override
public int cost() {
return super.cost() + 2;
}
}
使用装饰者模式
可以无限装饰,每装饰一次都需要new一次对象
public static void main(String[] args) {
//先定义一个不加料的煎饼
BatterCake batterCake = new BatterCakeNormal();
//开始装饰
batterCake = new EggDecorator(batterCake);
batterCake = new EggDecorator(batterCake);
batterCake = new SausageDecorator(batterCake);
batterCake = new SausageDecorator(batterCake);
System.out.println(batterCake.getDesc() + ":" + batterCake.cost());
}
运行结果为
小结
每加一个装饰的操作就需要新建一个装饰者类
不能摆脱继承,只是在继承的基础上增强