裝飾者模式

定義

裝飾者模式,動態地將責任附加到對象上。若要擴展功能,裝飾者提供了比繼承更具有彈性的替代方案。

抽象構件(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());
    }

}

思考

裝飾着和被裝飾者相同的接口,因爲裝飾者必須能取代被裝飾者。
我們可以多個裝飾者包裝一個對象。
裝飾者可以在所委託被裝飾者行爲之前/或之後,加上自己的行爲,以達到定的目的。其實者裏面的意思就是我們是如何算出一杯星巴克的價格,我們在之前取出了調用者本身的價格。

發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章