裝飾者(Decorator)模式就是在不修改任何底層代碼的狀況下,給對象賦予新的職責。編程
裝飾者模式又稱包裝模式,即:在真實對象的外層包裝一層層新的職能。設計模式
裝飾者模式主要採用組合的方式拓展對象的行爲,是給愛用繼承的人一個全新的設計眼界。(繼承是在編譯時靜態決定對象的行爲,而組合是在運行時動態地擴展對象的行爲。)架構
須要格外注意的是:裝飾者與被裝飾者必須是同一個類型,即:具備相同的超類。【這裏經過繼承實現類型匹配】ide
裝飾者模式包含四個角色:抽象目標組件,具體目標組件,抽象裝飾者,具體裝飾者。其中,目標組件就是須要被裝飾的對象。優化
1.抽象目標組件(Component)this
目標組件的抽象類,是全部裝飾者與具體組件的超類。這是爲了保持組件被裝飾後,返回的對象類型保持不變。spa
public abstract class Beverage { protected String description = "Unknown Beverage"; public String getDescription() { return description; } public abstract BigDecimal cost(); }
2.具體目標組件設計
須要賦予新權限的組件。3d
public class DarkRoast extends Beverage{ public DarkRoast() { description = "Dark Roast"; } @Override public BigDecimal cost() {
//定義深焙飲料的價格 return new BigDecimal(0.25); } }
3.抽象裝飾者code
//須要在飲料中添加的調味品
//具備兩個抽象方法:getDescription()、cost()
public abstract class Condiment extends Beverage { public abstract String getDescription(); }
4.具體裝飾者
public class Mocha extends Condiment{ private Beverage beverage; public Mocha(Beverage beverage) { super(); this.beverage = beverage; } @Override public String getDescription() {
//在原有飲料的描述中增添添加劑的描述 return beverage.getDescription() + ", Mocha"; } @Override public BigDecimal cost() {
//返回飲料加上添加劑的總價。0.6是摩卡添加劑的價格 return new BigDecimal(0.6).add(beverage.cost()).setScale(2, BigDecimal.ROUND_HALF_UP); } }
public class Whip extends Condiment{ private Beverage beverage; public Whip(Beverage beverage) { super(); this.beverage = beverage; } @Override public String getDescription() { return beverage.getDescription() + ", Whip"; } @Override public BigDecimal cost() { return new BigDecimal(0.5).add(beverage.cost()).setScale(2, BigDecimal.ROUND_HALF_UP); } }
5.Demo
public class BeverageDemo { public static void main(String[] args) { Beverage beverage = new DarkRoast(); System.out.println(beverage.getDescription() +" : " + beverage.cost()); //use mocha & whip to decorate dark-roast. beverage = new Mocha(beverage); beverage = new Whip(beverage); System.out.println(beverage.getDescription() +" : " + beverage.cost()); /*Log: * Dark Roast : 0.25 * Dark Roast, Mocha, Whip : 1.35*/ } }
6.備註
9. 補充
Java I/O是裝飾者模式的典型例子。
10. 參考資料
10.1 O'Reilly:《Head First設計模式》
10.2 百度百科 : 《裝飾者模式》