設計模式之裝飾者模式(二)

歡迎你們的不嫌棄,繼續和我一塊兒學習設計模式。上一篇已經把裝飾者模式的類圖有了一個總體的出來,末尾說的去想一想實現的代碼,你實踐了嗎?是什麼緣由讓你實踐了呢?又是什麼緣由讓你沒有動手呢?沒動手,多是思路還不夠明確是嗎?html

接下來,咱們繼續學習。經過代碼實現的方式,來搞定裝飾者模式。java

寫下代碼

動手的時候來啦,咱們先從Beverage類下手。這不須要修改原有的設計,以下所示:git

/**
 * 
 * @Description: Beverage是一個抽象類,有兩個方法:getDescription()以及cost()
 * @author:XuYue
 */
public abstract class Beverage {
    String description = "Unknown Beverage";
    
    // getDescription()已經在此實現了,可是cost()必須在子類中實現
    public String getDescription() {
        return description;
    }
    
    public abstract double cost();
}

而後咱們繼續實現Condiment(調料)抽象類,也就是裝飾者類:github

/**
 * 
 * @Description: 必須讓CondimentDecorator可以取代Beverage,因此將CondimentDecorator擴展自Beverage類
 */
public abstract class CondimentDecorator extends Beverage {
    // 全部的調料裝飾者都必須從新實現getDescription()方法,稍後說明緣由
    public abstract String getDescription();
}

寫飲料的代碼

有了上面的基礎,即已經有了基類,那咱們就能夠愉快的把飲料類實現了。先從濃縮咖啡(Espresso)開始吧。在這,咱們須要實現cost()方法以及將描述設置清楚。其餘類,在代碼裏表現,就不在文中體現啦。設計模式

/**
 * 
 * @Description:首先,讓Espresso擴展自Beverage類,由於Espresso是一種飲料
 * @author:XuYue
 */
public class Espresso extends Beverage {

    public Espresso() {
        // 爲了要設置飲料的描述,咱們寫了一個構造器,description繼承自Beverage
        description = "Espresso";
    }
    
    // 須要計算Espresso的價錢
    @Override
    public double cost() {
        return 1.99;
    }

}

寫調料代碼

還記得上篇中的類圖嗎,根據類圖咱們已經完成了抽象組件(Beverage),有了具體組件(HoustBlend),也有了抽象裝飾者(CondimentDecorator)。那麼,就差實現具體的裝飾者了,也就是咱們的調料。這裏是列舉Mocha,其餘的自行實現哦。小編提供的代碼裏已經實現啦, 感興趣的小夥伴,能夠寫完和小編的PK下。ide

/**
 * 
 * @Description:
 * 摩卡是一個裝飾者,因此讓它擴展自CondimentDecorator
 * CondimentDecorator擴展自Beverage
 * @author:XuYue
 */
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();
    }

}

供應咖啡

恭喜你,經歷過以前的準備,是時候坐下來休息休息,點一杯咖啡享受下人生啦。來看看你的裝飾者模式設計出來的系統吧。學習

寫以前,咱們先看看雙倍摩卡咖啡的是怎麼裝飾的吧。其實就是上一篇中的單倍摩卡,再加一層摩卡的裝飾類便可,是否是很神奇呢。
this

public class StarbuzzCoffee {

    public static void main(String[] args) {
        // 訂一杯Espresso,不須要調料
        Beverage beverage = new Espresso();
        System.out.println(beverage.getDescription() + " $" + beverage.cost());
        
        // 訂一杯雙倍Mocha加Whip的DarkRoast()咖啡
        Beverage beverage2 = new DarkRoast();
        // 用Mocha裝飾它
        beverage2 = new Mocha(beverage2);
        // 用第二個Mocha裝飾它
        beverage2 = new Mocha(beverage2);
        // 用Whip裝飾它
        beverage2 = new Whip(beverage2);
        System.out.println(beverage2.getDescription() + " $" + beverage2.cost());
        
        // 訂一杯調料爲Soy、Mocha、Whip的HouseBlend咖啡
        Beverage beverage3 = new HouseBlend();
        beverage3 = new Soy(beverage3);
        beverage3 = new Mocha(beverage3);
        beverage3 = new Whip(beverage3);
        System.out.println(beverage3.getDescription() + " $" + beverage3.cost());
        
    }
}

// 輸出結果
Espresso $1.99
Dark Roast Coffee , Mocha , Mocha , Whip $1.49
House Blend Coffee , Soy , Mocha , Whip $1.34

目前爲止,咱們已經把上篇遺留下來的類圖轉換成了代碼實現出來。當咱們在後面介紹到工廠和生成器模式的時候,將會有更好的方式創建被裝飾者對象。因此,儘管如今的裝飾者模式存在部分缺陷,但不妨礙咱們對這個模式的學習,後續的增長,只是對模式有更加深入的認知。設計

因此,此次的內容就先到這裏。下一篇,咱們針對性的對現有JDK中的裝飾者模式舉個例子,並對裝飾者模式作出總結。3d

留個小習題,在此次講的過程當中咱們是加了調料, 那咖啡廳裏如今都會有杯子的大小,小杯、中杯、大杯,並收取相應的價錢,該如何編寫呢?先拋個磚,咱們在Beverage類中加上getSize()和setSize()。下次小編會給出答案噢。

PS:代碼已經上傳,須要查看的朋友點擊此處HeadFirstDesign

推薦閱讀

設計模式之裝飾者模式(一)

愛生活,愛學習,愛感悟,愛挨踢

相關文章
相關標籤/搜索