什麼?沒看懂?不要緊,最後再來看這個概念,想讓讓咱們來看一個咖啡屋項目(就是點各式java
各樣的咖啡)。測試
本來的設計以下:this
看似很好的設計,可是別忘了,買咖啡時候咱們會讓他們給咱們加一系列的調料,例如蒸奶、spa
摩卡......。因此,在這時咖啡店的設計就變成了,以下:設計
不錯,你看到了類爆炸!3d
好啦,如今有對這個系統作出了改進,以下:code
好啦,如今這個設計相比以前的的確好了許多,可是若是咱們要修改配料呢?那麼就必須修改對象
超類,這時候就違反了一條設計原則:類應該對擴展開放,對修改關閉!blog
因此這個時候,裝飾者模式單誕生了!!!!!繼承
來看個例子:
若是顧客如今要一杯摩卡和奶泡深培咖啡。那麼,要作的是:
①拿一個深培咖啡(DarkRoast)對象
②以摩卡(Mocha)對象裝飾它
③以奶泡(Whip)裝飾它
④調用cost()方法,並依賴委託(delegate)將調料的幾千加上去
如何工做?
①以DarkRoast對象開始
②顧客想要摩卡(Mocha),因此創建一個Mocha對象,並用它將DarkRoast對象包起來
③顧客也想要奶泡(Whip),因此創建一個Whip裝飾者,並用它將Mocha對象包起來。別
忘了,DarkRoast繼承自Beverage,且有一個cost()方法,用來計算飲料價錢
④如今,該是爲顧客算錢的時候了。經過調用最外圈的裝飾者的cost就能夠辦到,以下圖:
好了,請記住裝飾者和被裝飾對象有相同的超類型!如今讓咱們寫一些代碼,瞭解他的工做吧:
首先看一下咱們如今的設計圖:
先從Beverage類下手,這不須要改變原始設計。以下圖:
1 public abstract class Beverage { 2 String description = "Unknown Beverage"; 3 4 public String getDescription(){ 5 return description; 6 } 7 8 public abstract double cost(); 9 }
Beverage很簡單。讓咱們來實現Condiment(調料)抽象類,也就是裝飾這類吧:
1 public abstract class CondimentDecorator extends Beverage{ 2 Beverage beverage; 3 4 public abstract String getDescription(); 5 }
如今,該是實現一些飲料的時候了!先從濃縮咖啡(Espresso)開始:
Espresso.java:
1 public class Espresso extends Beverage { 2 public Espresso() { 3 description = "Espresso"; 4 } 5 6 public double cost() { 7 return 1.99; 8 } 9 }
DarkRoast.java:
1 public class DarkRoast extends Beverage { 2 public DarkRoast() { 3 description = "Dark Roast Coffee"; 4 } 5 6 public double cost() { 7 return .99; 8 } 9 }
HouseBlend.java:
1 public class HouseBlend extends Beverage { 2 public HouseBlend() { 3 description = "House Blend Coffee"; 4 } 5 6 public double cost() { 7 return .89; 8 } 9 }
開始協調料代碼:
Mocha.java:
1 public class Mocha extends CondimentDecorator { 2 public Mocha(Beverage beverage) { 3 this.beverage = beverage; 4 } 5 6 public String getDescription() { 7 return beverage.getDescription() + ", Mocha"; 8 } 9 10 public double cost() { 11 return .20 + beverage.cost(); 12 } 13 }
Milk.java:
1 public class Milk extends CondimentDecorator { 2 public Milk(Beverage beverage) { 3 this.beverage = beverage; 4 } 5 6 public String getDescription() { 7 return beverage.getDescription() + ", Milk"; 8 } 9 10 public double cost() { 11 return .10 + beverage.cost(); 12 } 13 }
Soy.java:
1 public class Soy extends CondimentDecorator { 2 public Soy(Beverage beverage) { 3 this.beverage = beverage; 4 } 5 6 public String getDescription() { 7 return beverage.getDescription() + ", Soy"; 8 } 9 10 public double cost() { 11 return .15 + beverage.cost(); 12 } 13 }
Whip.java:
1 public class Whip extends CondimentDecorator { 2 public Whip(Beverage beverage) { 3 this.beverage = beverage; 4 } 5 6 public String getDescription() { 7 return beverage.getDescription() + ", Whip"; 8 } 9 10 public double cost() { 11 return .10 + beverage.cost(); 12 } 13 }
測試代碼:
Main.java:
1 public class Main { 2 3 public static void main(String[] args) { 4 Beverage beverage = new Espresso(); 5 System.out.println(beverage.getDescription() 6 + " $" + beverage.cost()); 7 8 Beverage beverage2 = new DarkRoast(); 9 beverage2 = new Mocha(beverage2); 10 beverage2 = new Mocha(beverage2); 11 beverage2 = new Whip(beverage2); 12 System.out.println(beverage2.getDescription() 13 + " $" + beverage2.cost()); 14 15 Beverage beverage3 = new HouseBlend(); 16 beverage3 = new Soy(beverage3); 17 beverage3 = new Mocha(beverage3); 18 beverage3 = new Whip(beverage3); 19 System.out.println(beverage3.getDescription() 20 + " $" + beverage3.cost()); 21 } 22 }
結果: