定义
装饰者模式,动态地将责任附加到对象上。若要扩展功能,装饰者提供了比继承更具有弹性的替代方案。
抽象构件(Component)角色:给出一个抽象接口,以规范准备接收附加责任的对象。
具体构件(ConcreteComponent)角色:定义一个将要接收附加责任的类。
装饰(Decorator)角色:持有一个构件(Component)对象的实例,并定义一个与抽象构件接口一致的接口。
具体装饰(ConcreteDecorator)角色:负责给构件对象“贴上”附加的责任。
背景
星巴克的咖啡DarkRoast超优深培的也有decaf低咖啡因的咖啡等品类,买咖啡的时候同时顾客可以加点蒸奶、豆浆、摩卡、或者奶泡等。
正解代码
public abstract class Beverage {
protected String description="";
public String getDescription(){
return description;
}
public abstract double cost();
}
public abstract class CondimentDecorator extends Beverage {
public abstract String getDescription();
}
//咖啡底料
public class HouseBlend extends Beverage {
public HouseBlend(){
description="House Blend coffee";
}
@Override
public double cost() {
return 4.9;
}
}
//加牛奶类
public class Milk extends CondimentDecorator {
protected Beverage beverage;
public Milk(Beverage beverage){
this.beverage=beverage;
}
@Override
public String getDescription() {
return beverage.getDescription()+",with milk";
}
@Override
public double cost() {
return 2.3+beverage.cost();
}
}
//加摩卡类
public class Mocha extends CondimentDecorator {
protected Beverage beverage;
public Mocha(Beverage beverage){
this.beverage=beverage;
}
@Override
public String getDescription() {
return beverage.getDescription()+",with Mocha";
}
@Override
public double cost() {
return 1.2+beverage.cost();
}
}
public class Starbuzz {
public static void main(String[] args) {
Beverage beverage2=new HouseBlend();
//稍微注意下这里被装饰者把自己赋值给了装饰者对象
beverage2=new Mocha(beverage2);
beverage2=new Mocha(beverage2);
beverage2=new Whip(beverage2);
System.out.println(beverage.getDescription()+":"+beverage.cost());
}
}
思考
装饰着和被装饰者相同的接口,因为装饰者必须能取代被装饰者。
我们可以多个装饰者包装一个对象。
装饰者可以在所委托被装饰者行为之前/或之后,加上自己的行为,以达到定的目的。其实者里面的意思就是我们是如何算出一杯星巴克的价格,我们在之前取出了调用者本身的价格。