三分鐘帶您搞懂裝飾模式

全文:959字,預計閱讀時間:8分鐘

定義:

  裝飾模式(Decorator)動態地給一個對象添加一些額外的職責。就增長功能來講,裝飾模式比生成子類更加靈活。
  這裏能夠舉一個生活中的例子,一個蛋糕,在蛋糕上擺上水果,這個蛋糕就變成了水果蛋糕,給這個水果蛋糕插上蠟燭,它就變成了一個生日蛋糕。(這是Head First中的一個例子,我的以爲很是的形象,記憶猶新)。

分析:

  若是咱們須要擴展一個類的功能,你會怎麼作呢?若是直接修改這個類,咱們就違反了開閉原則(對修改關閉,對擴展開放)。
  咱們能夠繼承這個類,寫一個這個類的子類,用於實現擴展功能,也可使用組合(將這個類做爲成員變量),達到相同的效果。
  咱們將繼承這種關係稱爲is-a,組合這種關係稱爲use-a。is-a的耦合程度要高於use-a,因此咱們常常能夠聽到這樣的說法:組合優於繼承,緣由就是這兩種關係的耦合程度不一樣。
裝飾模式的核心思想,其實就是用組合代替繼承。

圖解:

實例:

  這裏舉一個咖啡店的例子,咖啡的原料是咖啡豆,咱們可使用咖啡豆和牛奶、蜂蜜、摩卡組合出不一樣價格、不一樣口味的咖啡。
  這裏咖啡豆就是被裝飾的對象,也就是圖示中的ConcreteComponent,飲品類就是咱們抽象出的Component,定義了展現價格和材料兩個方法。牛奶、蜂蜜、摩卡是裝飾對象,也就是圖中的ConcreteDecoratorA、ConcreteDecoratorB。他們抽象出的Decorator,一樣定義了展現價格和材料兩個方法,具體類圖與實現以下:

 

 

代碼:

/**
 * 飲品.
 *
 * @author jialin.li
 * @date 2019-12-26 22:58
 */
public interface Beverage {
    /** 獲取描述 */
    String getDescription();
    /** 獲取金額 */
    double getPrice();
}
/**
 * 咖啡豆1
 *
 * @author jialin.li
 * @date 2019-12-26 22:59
 */
public class CoffeeBean1 implements Beverage {

    @Override
    public String getDescription() {
        return "第一種咖啡豆";
    }

    @Override
    public double getPrice() {
        return 10d;
    }
}
/**
 * 咖啡豆2
 *
 * @author jialin.li
 * @date 2019-12-26 23:00
 */
public class CoffeeBean2 implements Beverage{
    @Override
    public String getDescription() {
        return "第一種咖啡豆";
    }

    @Override
    public double getPrice() {
        return 12.5d;
    }
}
/**
 * 裝飾器.
 *
 * @author jialin.li
 * @date 2019-12-26 23:02
 */
public class Decorator implements Beverage{

    protected Beverage coffee;

    @Override
    public String getDescription() {
        return "裝飾器,由子類重寫方法";
    }

    @Override
    public double getPrice() {
        return 0;
    }
}
/**
 * 蜂蜜.
 *
 * @author jialin.li
 * @date 2019-12-26 23:07
 */
public class Honey extends Decorator {
    public Honey(Beverage coffee) {
        this.coffee = coffee;
    }

    @Override
    public String getDescription() {
        return coffee.getDescription() + "加蜂蜜";
    }

    @Override
    public double getPrice() {
        return coffee.getPrice() + 4.5d;
    }
}
/**
 * 牛奶.
 *
 * @author jialin.li
 * @date 2019-12-26 23:03
 */
public class Milk extends Decorator {
    public Milk(Beverage coffee) {
        this.coffee = coffee;
    }

    @Override
    public String getDescription() {
        return coffee.getDescription() + "加牛奶";
    }

    @Override
    public double getPrice() {
        return coffee.getPrice() + 1.5d;
    }
}
/**
 * 摩卡.
 *
 * @author jialin.li
 * @date 2019-12-26 23:05
 */
public class Mocha extends Decorator {
    public Mocha(Beverage coffee) {
        this.coffee = coffee;
    }

    @Override
    public String getDescription() {
        return coffee.getDescription() + "加摩卡";
    }

    @Override
    public double getPrice() {
        return coffee.getPrice() + 2.5d;
    }
}
/**
 * 測試類.
 *
 * @author jialin.li
 * @date 2019-12-26 23:09
 */
public class Main {
    public static void main(String[] args) {
        CoffeeBean1 coffee1 = new CoffeeBean1();
        CoffeeBean2 coffee2 = new CoffeeBean2();

        // 加蜂蜜
        Beverage honey = new Honey(coffee1);
        // 加摩卡
        Beverage mocha = new Mocha(honey);
        System.out.println(mocha.getDescription());
        System.out.println(mocha.getPrice());

        // 加牛奶
        Milk milk = new Milk(coffee2);
        System.out.println(milk.getDescription());
        System.out.println(milk.getPrice());
    }
}

結果:

  第一種咖啡豆加蜂蜜加摩卡
  17.0
  第一種咖啡豆加牛奶
  14.0
相關文章
相關標籤/搜索