Head First設計模式(三)、裝飾者模式

裝飾者模式:

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

特點:

1、裝飾者和被裝飾對象有相同的超類型。

2、你可以用一個或多個裝飾者包裝一個對象。

3、既然裝飾者和被裝飾對象有相同的超類型,所以在任何需要原始對象(被包裝的)的場合,可以用裝飾過的對象代替它。

4、裝飾者可以再所委託被裝飾者的行爲之前與/或之後,加上自己的行爲,以達到特定的目的。

5、對象可以在任何時候被裝飾所以可以在運行時動態地、不限量地用你先的裝飾者來裝飾對象。

實例:

購買咖啡是,可以要求在其中假如各種調料,例如:豆漿、摩卡、或者奶泡,根據所加入的調料收取不同的費用。

以裝飾者模式構造:

類圖:

話不多說,直接上代碼:

/**

 * 飲料類

 *

 */

public abstract class Beverage {

     //描述

    String description = "Unknown Beverage";

 

    public String getDescription(){

        return description;

    }

 

     //結算方法

     public abstract double cost();

}

 

/**

 * 調料抽象類,也就是裝飾者類

 *

 */

//必須讓CondimentDecorator能夠取代Beverage,所以將CondimentDecorator擴展自Beverage

public abstract class CondimentDecorator extends Beverage{

 

    //所有調料裝飾者必須重新實現此方法

    public abstract String getDescription();

 

}

 

/**

 * 濃縮咖啡

 *

 */

public class Espresso extends Beverage{

 

    public Espresso(){

       //爲了設置飲料的描述,我們寫了一個構造器

       description = "Espresso";

    }

 

    @Override

    public double cost() {

        //飲料的價錢

        return 1.99;

    }

 

}

 

/**

 * 摩卡裝飾者

 *

 */

public class Mocha extends CondimentDecorator{

    //要讓mocha能夠引用一個Beverage,做法如下

    //1、用一個實例變量記錄飲料,也就是被裝飾者

    Beverage beverage;

    //2、想辦法讓被裝飾者被記錄到實例變量中,這裏的做法是:把飲料當做構造器的參數,再由構造器將此飲料記錄在實例變量中

    public Mocha(Beverage beverage){

        this.beverage = beverage;

    }

 

    @Override

    public String getDescription() {

        // 我們希望描述不只是描述飲料,而是完整的連調料也描述出來,所以首先利用委託的做法,得到一個描述,然後在其後加上附加的敘述

        return beverage.getDescription() + ",Mocha";

    }

 

    @Override

    public double cost() {

        //需要計算帶mocha飲料的價錢,首先把調用委託給被裝飾對象,以計算價格,然後再加上摩卡的價錢,得到最後結果

        return 0.2 + beverage.cost();

    }

 

}

 

public class CoffeeTest {

    //測試類

    public static void main(String[] args) {

        //訂一杯濃縮咖啡,不需要飲料

        Beverage beverage = new Espresso();

        System.out.println(beverage.getDescription() + " $" +beverage.cost());

        //訂一杯濃縮咖啡,需要mocha

        Beverage beverage2 = new Espresso();

        beverage2 = new Mocha(beverage2);

        System.out.println(beverage2.getDescription() + " $" +beverage2.cost());

    }

}

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