java设计模式——装饰者模式
装饰者模式
一 问题的引入
Starbuzz是一家咖啡连锁店,他们准备更新订单系统,这是他们原先的设计,他们准备更新订单系统,以和服他们饮料的供应需求。
解决方案
A.使用继承
每个cost()方法计算出每种搭配的价格。
评价:很明显这种方法不可取。
B从Beverage基类下手,加上实例变量代表是否加上某种配料(牛奶,豆浆,mocha).
评价:如果加双倍mocha怎么办?调料价格的改变会导致改变我的代码?……………..
C 装饰者模式解决
如顾客想要一杯mocha和奶泡深焙咖啡那么要做的事情是:
1.那一个深焙咖啡(DarkRoast)对象。
2.以Mocha对象装饰它。
3.以奶泡(Whip)对象装饰它。
4.调运cost()方法,并依赖委托将各个价格加上去。
如何“装饰”一个对象又如何“委托”呢?图解
装饰者模式类图:
Starbuzz的具体解决方案:
代码:
Beverage基类:
public abstract class Beverage {
/*
*
* Beverage 抽象类。
*/
String description="Unkonwn Beverage";
public String getDescription(){
return description;
}
public abstract double cost();
}
Condiment抽象类:
public abstract class CondimentDecorator extends Beverage {
/*
*
* (non-Javadoc)
*condiment 调料的抽象类 也就是装饰类的抽象类
*/
public abstract String getDescription();
}
组件类:
public class HouseBlend extends Beverage {
public HouseBlend(){
description="HouseBlend";
}
@Override
public double cost() {
// TODO Auto-generated method stub
return 0.89;
}
}
装饰者类(配料类):
public class Mocha extends CondimentDecorator {
Beverage beverage;
public Mocha(Beverage beverage){
this.beverage=beverage;
}
@Override
public String getDescription() {
return beverage.getDescription()+",Mocha";
}
@Override
public double cost() {
return 0.20+beverage.cost();
}
}
测试类:
public class DecorateTest {
public static void main(String[] args) {
Beverage beverage=new Espresso();
System.out.println(beverage.getDescription()+"$"+beverage.cost());
Beverage beverage2=new HouseBlend();
beverage2=new Mocha(beverage2);
beverage2=new Mocha(beverage2);
beverage2.getDescription();
System.out.println(beverage2.getDescription()+"$"+beverage2.cost());
}
}
总结:
装饰者模式:动态的将责任附加到对象上。若要扩展功能,装饰者提供了更有弹性的替代方案
缺点:类太多了,不容易一下子搞清楚,Java I/O的设计正是装饰者模式。
以上内容全部来源于《head first 设计模式》如果想详细了解请参考原书。