讀《HeadFirst設計模式》筆記之裝飾者模式

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

特色:this

  • 裝飾者和被裝飾對象有相同的超類型。
  • 你能夠用一個或多個裝飾者包裝一個對象。
  • 既然裝飾者和被裝飾對象有相同的超類型,因此在任何須要原始對象(被包裝的)的場合,能夠用裝飾過的對象代替它。
  • 裝飾者能夠在所委託被裝飾者的行爲以前與/或以後,加上本身的行爲,以達到特定的目的。
  • 對象能夠在任什麼時候候被裝飾,因此能夠在運行時動態地、不限量地用你喜歡的裝飾者來裝飾對象。

 舉個栗子:設計

領導給你分配設計一個咖啡收款系統。咖啡能夠加配料,不一樣的配料收費不一樣。怎麼設計一個靈活的系統呢?思考三秒鐘3d

若是一個顧客想要摩卡(Mocha)和奶泡(Whip)深焙咖啡(DarkRoast),使用裝飾者模式怎麼作呢?code

一、以DarkRoast對象開始對象

二、顧客想要摩卡(Mocha),因此創建一個Mocha對象,並用它將DarkRoast對象包(wrap)起來。blog

三、顧客也想要奶泡(Whip),因此須要創建一個Whip裝飾者,並用它將Mocha對象包起來。別忘了,DarkRoast繼承自Beverage,且有一個cost()方法,用來計算飲料價錢。繼承

四、如今,該是爲顧客算錢的時候了。經過調用最外圈裝飾者(Whip)的cost()就能夠辦獲得。Whip的cost()會先委託它裝飾的對象(也就是Mocha)計算出價錢,而後再加上奶泡的價錢。ip

 

代碼實現:get

咖啡抽象類:

public abstract class Beverage {
    String description = "Unknown Beverage";

    public String getDescription() {
        return description;
    }

    public abstract double cost();
}

配料抽象類,繼承咖啡抽象類:

public abstract class CondimentDecorator extends Beverage {
    public abstract String getDescription();
}

咖啡的實現:

// 濃咖啡
public class Espresso extends Beverage {
    public Espresso() {
        description = "Espresso";
    }

    public double cost() {
        return 1.99;
    }
}

// 深焙咖啡
public class DarkRoas extends Beverage {
    public DarkRoas () {
        description = "Dark Roas Coffee";
    }

    public double cost() {
        return 0.89;
    }
}

配料實現:

public class Mocha extends CondimentDecorator {
    Beverage beverage;
    public Mocha(Beverage beverage) {
        this.beverage = beverage;
    }

    public String getDescription() {
        return beverage.getDescription() + ", Mocha";
    }
    public double cost() {
        return 0.20 + beverage.cost();
    }
}

來一杯咖啡:

public class StarbuzzCoffee {
    public static void main(String args[]) {
        // 一杯不加配料的濃咖啡
        Beverage beverage = new Espresso();
        System.out.println(beverage.getDescription() + ": $" + beverage.cost());

        // 雙倍摩卡和奶泡深焙咖啡
        Beverage beverage2 = new DarkRoast();
        beverage2 = new Mocha(beverage2);
        beverage2 = new Mocha(beverage2);
        beverage2 = new Whip(beverage2);
        System.out.println(beverage2.getDescription() + ": $" + beverage2.cost());

        // 再來一杯調料爲豆漿、摩卡、奶泡的HouseBlend咖啡
        Beverage beverage3 = new HouseBlend();
        beverage3 = new Soy(beverage3);
        beverage3 = new Mocha(beverage3);
        beverage3 = new Whip(beverage3);
        System.out.println(beverage3.getDescription() + ": $" + beverage3.cost());
    }
}

相關文章
相關標籤/搜索