装饰模式是为已有功能动态地添加更多功能的一种方式.
把类中的装饰功能从类中搬移去除,可以简化原有的类
动态的给一个对象添加一些额外的职责,就增加功能来说,装饰模式比生成子类更为灵活
当系统需要新功能的时候,是向旧的类中添加新的代码.这些新加的代码通常装饰了原有类的核心职责或主要行为,
它们在主类中加入了新的字段,新的方法和新的逻辑,从而增加了主类的复杂度.而这些新加入的东西仅仅是为了满足一些只在某种特定情况下才会执行的特殊行为的需要.
装饰模式把每个要装饰的功能房在单独的类中,并让这个类包装它所要装饰的对象.当需要执行特殊行为时,客户可以根据需要有选择的按顺序使用装饰功能包装对象 (如IO流中的节点流和处理流 处理流即为具体装饰器如BufferReader等 类似例子中的Milk和Sugar)
装饰模式分为4部分:
1.抽象组件Component:对应Coffee类
2.具体组件ConcreteComponent:对应具体的咖啡,被装饰的对象
3.装饰抽象类(可以不写)
4.继承抽象类的具体装饰器
取一个往coffee中加调料的例子
/**
* 最高级接口类同IO流的InputStream和OutputStream
* @author guk
*
*/
public interface Drink {
public float cost();
}
/**
* 调味品抽象类即装饰抽象类同IO流的FilterOutputStream
* @author guk
*
*/
public abstract class CondimentDecorator implements Drink {
protected Drink drink;
// 装饰模式的核心是构造器内传入的是接口对象,而不是具体类 所以可以给被装饰者一直加修饰
public CondimentDecorator(Drink drink) {
this.drink=drink;
}
@Override
public float cost() {
return drink.cost();
}
}
/**
* 被装饰者类
* @author guk
*
*/
public class Coffee implements Drink {
@Override
public float cost() {
System.out.println("一杯咖啡10元");
return 10;
}
}
public class Milk extends CondimentDecorator {
public Milk(Drink drink) {
super(drink);
}
@Override
public float cost() {
System.out.println("加牛奶+2元");
return super.cost()+2;
}
}
public class Sugar extends CondimentDecorator {
@Override
public float cost() {
System.out.println("加糖加1元");
return super.cost()+1;
}
public Sugar(Drink drink) {
super(drink);
}
}
public static void main(String[] args) throws FileNotFoundException {
Drink drink=new Milk(new Sugar(new Coffee()));
System.out.println(drink.cost());
}