定義
裝飾者模式,動態地將責任附加到對象上。若要擴展功能,裝飾者提供了比繼承更具有彈性的替代方案。
抽象構件(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());
}
}
思考
裝飾着和被裝飾者相同的接口,因爲裝飾者必須能取代被裝飾者。
我們可以多個裝飾者包裝一個對象。
裝飾者可以在所委託被裝飾者行爲之前/或之後,加上自己的行爲,以達到定的目的。其實者裏面的意思就是我們是如何算出一杯星巴克的價格,我們在之前取出了調用者本身的價格。