装饰器模式是对继承的增强。就是套娃。
以做蛋糕为例,从蛋糕胚,到抹奶油,再到放上水果,一点点的把蛋糕胚装点成好看的蛋糕。
Show You The Code
首先是基础款蛋糕
public abstract class AbstractCake {
protected abstract String describe();
protected abstract String operate();
}
/**
* 基础版蛋糕,只有蛋糕胚
*/
public class Cake extends AbstractCake{
protected String describe() {
return "一个普通的蛋糕胚";
}
protected String operate() {
return "制作蛋糕胚";
}
}
创建两个装饰器,一个是给蛋糕加奶油,另一个是给蛋糕加草莓
/**
* 奶油装饰
*/
public class ButterDecorator extends AbstractCake{
private AbstractCake cake;
//重要的是这里,任何装饰过没被装饰过的蛋糕都被放到这里,然后就能一层层的嵌套
public ButterDecorator(AbstractCake cake){
this.cake = cake;
}
protected String describe() {
//加号是精髓,不断套娃,不断在上一版上加新东西
return this.cake.describe()+",抹上了奶油";
}
protected String operate() {
return "抹奶油";
}
}
装饰器模式的精髓在于,装饰器本质上也是继承的Cake,然后构造方法对各种cake来者不拒,从而允许了装饰器的无限套娃。
describe()方法中的加号正体现了套娃的精髓,就是加加加加加。
/**
* 水果装饰
*/
public class FruitDecorator extends AbstractCake{
private AbstractCake cake;
public FruitDecorator(AbstractCake cake){
this.cake = cake;
}
protected String describe() {
return this.cake.describe()+",点缀上了草莓";
}
protected String operate() {
return "加草莓";
}
}
测试类
public class CakeTest {
public static void main(String[] args) {
AbstractCake cake = new Cake();
System.out.println(cake.describe());
cake = new ButterDecorator(cake);
System.out.println(cake.describe());
cake = new FruitDecorator(cake);
System.out.println(cake.describe());
}
}
输出
JDK中最体现装饰器模式的精髓是IO流的那一堆类,可以看参考文献4,写的非常赞
参考文献