Head First Design Patterns (這是一本學Design Pattern 很好的書,漫畫形式,很易看易懂)
參考連結:
Wiki Decorator Pattern
神人對Decorator Pattern 的文章 (這篇文章好清楚,如果沒有書看這個也很簡單易明。)
簡單來說,如果有一些物件是同時有[相同特性]和[相似特性]時,就很適合用Decorator Pattern。
就舉台式飲品為例,各式台式飲品都有相同的特性,例如產品名稱、基本價格、等等。
也可以相似的特性,例如加各式配料,加珍珠、加仙草、等等
在這個例子,相同的特性就放在Component 去實現,相似特性就放到Decorator 去實現。
Component 的抽象類別,將相同的特性如產品名稱、基本價格都放在這裡:
package decorator.beverage; public abstract class Beverage { String description = "Unknown Beverage"; public String getDescription(){ return description; } public abstract double cost(); }
Component 的實作,假設我們的小店只有奶茶和奶綠兩種飲品:
package decorator.beverage; public class MilkTea extends Beverage { // override the abstract class description public MilkTea(){ description = "Milk Tea"; } // implement the abstract method public double cost() { return 1.99; } }
package decorator.beverage; public class MilkGreenTea extends Beverage { // override the abstract class description public MilkGreenTea(){ description = "Milk GreenTea"; } // implement the abstract method public double cost() { return 2.99; } }
然後就是Decroator 的抽象類別:
package decorator.beverage.flavouring; import decorator.beverage.Beverage; public abstract class FlavouringDecorator extends Beverage { // Decorator should reimplement this to decorate the beverage public abstract String getDescription(); }
然後是Decorator 的實作,假設我們有三種Decorator,冰的、加珍珠、加仙草:
package decorator.beverage.flavouring; import decorator.beverage.Beverage; public class Iced extends FlavouringDecorator { Beverage drink; //Decorator must have the base beverage public Iced(Beverage drink){ this.drink = drink; } // Decorate the description of the beverage public String getDescription() { return "Iced " + drink.getDescription(); } // Add the cost of Jelly to the beverage public double cost() { return drink.cost() + 0.20; } }
package decorator.beverage.flavouring; import decorator.beverage.Beverage; public class Pearl extends FlavouringDecorator { Beverage drink; //Decorator must have the base beverage public Pearl(Beverage drink){ this.drink = drink; } // Decorate the description of the beverage public String getDescription() { return drink.getDescription() + ", with Pearl"; } // Add the cost of pearl to the beverage public double cost() { return drink.cost() + 0.5; } }
package decorator.beverage.flavouring; import decorator.beverage.Beverage; public class Jelly extends FlavouringDecorator { Beverage drink; //Decorator must have the base beverage public Jelly(Beverage drink){ this.drink = drink; } // Decorate the description of the beverage public String getDescription() { return drink.getDescription() + ", with Jelly"; } // Add the cost of Jelly to the beverage public double cost() { return drink.cost() + 0.70; } }
最後就是我們的小店貢X開店了,我們點了三種飲品,分別是凍仙草奶茶、珍珠奶綠、凍珍珠奶茶......
package decorator; import decorator.beverage.*; public class GongTea { public static void main(String[] args) { //凍仙草奶茶 Beverage beverage1 = new MilkTea(); beverage1 = new Iced(beverage1); beverage1 = new Jelly(beverage1); System.out.println("Beverage1 is " + beverage1.getDescription() + ", price is $" + beverage1.cost()); //珍珠奶綠 Beverage beverage2 = new MilkGreenTea(); beverage2 = new Pearl(beverage2); System.out.println("Beverage2 is " + beverage2.getDescription() + ", price is $" + beverage2.cost()); //凍珍珠奶茶 Beverage beverage3 = new MilkTea(); beverage3 = new Iced(beverage3); beverage3 = new Pearl(beverage3); System.out.println("Beverage3 is " + beverage3.getDescription() + ", price is $" + beverage3.cost()); } }
運行的結果如下:
沒有留言:
張貼留言