設計模式之裝飾者模式

首先讓咱們看一下裝飾者模式(我愛叫他套娃模式)的概念:動態的將責任附加到對象上,

                                            若要擴展功能,裝飾者提供了比繼承者更有彈性的集成方案。

什麼?沒看懂?不要緊,最後再來看這個概念,想讓讓咱們來看一個咖啡屋項目(就是點各式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 }

結果:

相關文章
相關標籤/搜索