一:case context:咖啡店产品管理系统
饮料基类abstract Beverage{cost();}, 两种饮料子类HouseBlend,Decaf都实现了cost()方法。每种饮料有自己的价钱,如果加牛奶糖等condiments按份算钱。
二:目前实现:
基类增加milk,sweet等属性,增加hasMilk,hasSweet等方法,cost()实现时根据hasMilk()等判断计算。
问题:1:condiments价格变化必须改变已有代码。
2:增加新的condiments必须修改基类。
3:把所有condiments都作为基类的属性不合适,因为不是每个子类必须的,比如某些可能不适合Tea等饮料。
4:如果顾客需要多份condiments没办法计算。
三:
Design principal(open-close principal): Classes should be open for extension,but close for modification.
The Decorator pattern :attaches additional responsibilities to a object dynamically.Decorator provide a flexible alternative to subclassing for extending functionality.
现实方法:
public abstract CondimentDecorator extends Beverage{}
public Mocha extends CondifmentDecorator{
private Beverage beverage;
public Mocha(Beverage beverage){
this.beverage=beverage;
}
public float cost(){
return beverage.cost()+0.9;
}
public String getDescription(){
reuturn beverage.getDescription+" Mocha";
}
}
//--client test
Beverage beverage=new HouseBlend();
beverage=new Mocha(beverage);
beverage=new Mocha(beverage);
beverage=new Milk(beverage);
System.out.println(beverage.getDescription()+beverage.cost());
说明:
1:decorators继承被包装的类的基类,不是为了代码重用,而是为了有一个相同的基类,这样包装一次之后其基类还是被包装类的基类,所以可以继续包装。
2:decorator有一个被包装类属性,这样decorator在被包装类取得信息后在做处理。
四:when
1:当需要扩展一个类的功能,或给一个类增加新的behavior;
2:需要动态给一个对象增加功能,这些功能可以再动态的撤销。
3:需要增加有一些基本功能的排列组合而产生的非常大量的功能,从而使继承关系变得不现实。
五:现实使用
1:java I/O 类:abstract component-》InputStream,abstract decorator-》FilterInputStream,
decorator-》BufferInputStream,LineNumberInputStream
2:文本过滤系统