設計模式——裝飾者模式

定義

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

OO原則

  • 封裝變化
  • 多用組合少用繼承
  • 針對接口編程,不針對實現編程
  • 爲了交互對象之間的鬆耦合而努力
  • 類應該對擴展開放,對修改關閉

開閉原則

咱們的目標是使類容易擴展,在不改變現有代碼的狀況下,就能夠搭配新的行爲編程

認識裝飾者模式

以星巴此咖啡爲例。好比,客戶想要摩卡和奶泡深賠咖啡。那麼,要作的是:函數

  1. 那一個深賠咖啡(DarkRoast)對象
  2. 以摩卡(Mocha)對象裝飾它
  3. 以奶泡(Whip)對象裝飾它
  4. 調用cost()方法,並依賴委託將調料的價格加上去

圖片描述

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

類圖

圖片描述

實例

//component類
public abstract class Beverage {
    String description = "Unknown Beverage";
    
    public String getDescription() {
        return description;
    }
    
    public abstract double cost(); // cost()必需要在子類中實現
}

//裝飾者抽象類Decorator類
public abstract class CondimentDecorator extends Beverage { //首先,必須讓CondimentDecorator能取代Beverage,因此將CondimentDecorator擴展自Beverage類
    public abstract String getDescription(); //全部的飲料都必須從新實現getDescription()方法。
}

//ConcrectComponent類,具體的飲料類
public class Espresso extend Beverage {
    public Espresso() {
        this.description = "Espresso"; //爲了要充值飲料的描述,咱們寫了一個構造函數
    }
    
    public cost() {
        return 1.99;
    }
}

public class HouseBlend extend Beverage {
    public HouseBlend() {
        this.description = "House Blend Coffee"; 
    }
    
    public cost() {
        return .89;
    }
}

//裝飾這類ConcreteDecorator類
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 .20 + beverage.cost();
    }
}

測試代碼:測試

Beverage beverage = new HouseBlend();
beverage = new Soy(beverage); // $.15
beverage = new Mocha(beverage);
beverage = new Whip(beverage); // $.10

// House Blend Coffee,Soy,Mocha,Whip $1.34
相關文章
相關標籤/搜索