動態地將責任附加到對象上,若要擴展功能,裝飾着提供了比繼承更有彈性的替代方案。
咱們的目標是使類容易擴展,在不改變現有代碼的狀況下,就能夠搭配新的行爲編程
以星巴此咖啡爲例。好比,客戶想要摩卡和奶泡深賠咖啡。那麼,要作的是:函數
//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