收入这么少,我哪需要那么多支付方式?~~
接下来正式开始编写书中的案例了,虽然基本都是书中的代码,不过写写运行一下也很不错的
饮料,调料,咖啡类型类图如下:
首先编写一个抽象类
package com.zl.decorate.one;
public abstract class Beverage {
public String description="不知名的咖啡";//这里已经给description赋值了
public abstract double cost();//该方法是在每个子类去实现的
public String getDescription() {
return description;
}
}
实现调料抽象类,也就是装饰类:
package com.zl.decorate.one;
public abstract class CondimentDecorate extends Beverage {
public abstract String getDescription();//每个子类都需要实现描述
}
编写被装饰者:定义一中饮料体(浓缩咖啡):
package com.zl.decorate.one;
public class Espresso extends Beverage {
public Espresso(){//为了设置饮料的描述,我们写了一个构造器。description实例变量是继承自该Beverage
description="Espresso";
}
@Override
public double cost() {//返回不加调料的价钱
// TODO Auto-generated method stub
return 1.99;
}
}
另一种饮料主体
package com.zl.decorate.one;
public class HouseBlend extends Beverage {
public HouseBlend(){
description="HouseBlend";
}
@Override
public double cost() {
// TODO Auto-generated method stub
return 0.89;
}
}
编写调料类:
要让Mocha能够引用一个Beverage,做法如下:
(1)用一个实例变量记录饮料,也就是被装饰者。
(2)把饮料当做构造器的参数,再由构造器将此饮料记录在实例变量中
package com.zl.decorate.one;
public class Mocha extends CondimentDecorate {
Beverage beverage;
public Mocha(Beverage beverage){
this.beverage=beverage;
}
@Override
public String getDescription() {//beverage.getDescription()这里便用了委托,得到一个描述,并且加上新的部分
return beverage.getDescription()+",Mocha";
}
@Override
public double cost() {
// TODO Auto-generated method stub
return 0.20+beverage.cost();
}
}
package com.zl.decorate.one;
public class Whip extends CondimentDecorate {
Beverage beverage;
public Whip(Beverage beverage){
this.beverage=beverage;
}
@Override
public String getDescription() {
// TODO Auto-generated method stub
return beverage.getDescription()+",Whip";
}
@Override
public double cost() {
// TODO Auto-generated method stub
return beverage.cost()+0.39;
}
}
进行测试:
package com.zl.decorate.one;
public class TestDecorate {
/**
* @param args
*/
public static void main(String[] args) {
// TODO Auto-generated method stub
Beverage beverage=new Espresso();
System.out.println(beverage.getDescription()+"$"+beverage.cost());
Beverage houseBlend=new HouseBlend();
houseBlend=new Mocha(houseBlend);
houseBlend=new Whip(houseBlend);
System.out.println(houseBlend.getDescription()+"$"+houseBlend.cost());
}
}
装饰者模式小结:
1.装饰者和被装饰者对象有相同的超类型。
2.你可以用一个或多个装饰者包装一个对象。
3.既然装饰者和被装饰对象有相同的超类型,所以任何需要原始对象(被包装的)的场合可以用装饰过的对象代替它。
4.装饰者可以在所委托被装饰者的行为之前与/或之后,加上自己的行为,以达到特定的目的。
5.对象可以在任何时候被装饰,所以可以在运行时动态地,不限量地用你喜欢的装饰装饰者来对象。