寫在前面的話:java
該模式動態的將責任附加到對象上,若要擴展功能,裝飾者提供了比繼承更有彈性的替代方案。裝飾者能夠在被裝飾者的行爲前面與/或後面加上本身的行爲,甚至將被裝飾者的行爲整個取代掉,而達到特定的目的。ide
該模式的實現意味着一羣裝飾者類,這些類反映出被裝飾的組件類型,用來包裝具體組件。測試
缺點在於,能夠用無數個裝飾者包裝一個組件,但會致使設計中出現許多小對象,若是過分引用,會讓程序變得很複雜。this
案例分析:設計
需求:模擬 StarbuzzCoffee 的訂單系統,咖啡原種類爲Espresso,HouseBlend,添加調料種類分別爲Soy,Mocha,Whip,對應不一樣的收費,杯子分爲大中小三種,分別對應不一樣的收費對象
代碼實現:blog
1)咖啡部分:繼承
public abstract class Beverage { String description = "Unknown Beverage"; public String getDescription(){ return description; } public abstract double cost(); } public class Espresso extends Beverage { public Espresso() { description = "Espresso"; } @Override public double cost() { return 1.99; } } public class HouseBlend extends Beverage { public HouseBlend() { description = "HouseBlend"; } @Override public double cost() { return 0.89; } }
2)調料部分:ip
public abstract class CondimentBeverage extends Beverage { public abstract String getDescription(); } public class Soy extends CondimentBeverage { Beverage beverage; public Soy(Beverage beverage) { this.beverage = beverage; } @Override public String getDescription() { return beverage.getDescription(); } @Override public double cost() { return 0.30+beverage.cost(); } } public class Mocha extends CondimentBeverage { Beverage beverage; public Mocha(Beverage beverage) { this.beverage = beverage; } @Override public String getDescription() { return beverage.getDescription(); } @Override public double cost() { return 0.20+beverage.cost(); } } public class Whip extends CondimentBeverage { Beverage beverage; public Whip(Beverage beverage) { this.beverage = beverage; } @Override public String getDescription() { return beverage.getDescription(); } @Override public double cost() { return 0.40+beverage.cost(); } }
3) 杯子選擇:get
public abstract class Size extends Beverage { public abstract String getDescription(); } public class BigSize extends Size { Beverage beverage; public BigSize(Beverage beverage) { this.beverage = beverage; } @Override public String getDescription() { return beverage.getDescription(); } @Override public double cost() { return 0.30+beverage.cost(); } } public class MiddleSize extends Size { Beverage beverage; public MiddleSize(Beverage beverage) { this.beverage = beverage; } @Override public String getDescription() { return beverage.getDescription(); } @Override public double cost() { return 0.20+beverage.cost(); } } public class SmalleSize extends Size { Beverage beverage; public SmalleSize(Beverage beverage) { this.beverage = beverage; } @Override public String getDescription() { return beverage.getDescription(); } @Override public double cost() { return 0.10+beverage.cost(); } }
4)測試代碼---生產訂單:
public class StarbuzzCoffee { public static void main(String[] args) { Beverage beverage1 = new Espresso(); //訂一杯Espresso,不添加任何調料 System.out.println(beverage1.getDescription()+":$"+beverage1.cost()); Beverage beverage2 = new HouseBlend(); //訂一杯HouseBlend,不添加任何調料 beverage2 = new Mocha(beverage2); beverage2 = new Mocha(beverage2); //兩份摩卡 System.out.println(beverage2.getDescription()+"(double Mocha):$"+beverage2.cost()); beverage2 = new Soy(beverage2); //再加一份soy System.out.println(beverage2.getDescription()+"(additional Soy):$"+beverage2.cost()); beverage2 = new Whip(beverage2); //再加一份whip System.out.println(beverage2.getDescription()+"(additional Whip):$"+beverage2.cost()); beverage2 = new MiddleSize(beverage2); //選擇中杯 System.out.println(beverage2.getDescription()+"(choose middleSize):$"+beverage2.cost()); } }
測試結果:
Espresso:$1.99HouseBlend(double Mocha):$1.29HouseBlend(additional Soy):$1.59HouseBlend(additional Whip):$1.99HouseBlend(choose middleSize):$2.19