posts - 310, comments - 6939, trackbacks - 0, articles - 3
            BlogJava :: 首頁 :: 新隨筆 :: 聯系 :: 聚合  :: 管理

          【Head First設計模式】-Decorator模式

          Posted on 2008-01-21 10:05 詩特林 閱讀(4333) 評論(2)  編輯  收藏 所屬分類: DesignPattern
           

          Head First設計模式】-Decorator模式

           

          一、要完成的任務

          星巴茲(Starbuzz)是以擴張速度最快而聞名的咖啡連鎖店。如果你在街角看到它的店,在對面街上肯定還會看到另一家。因為擴張速度實在太快了,他們準備更新訂單系統,以合乎他們的飲料供應要求。他們原先的類設計是這樣的……

           

          購買咖啡時,也可以要求在其中加入各種調料,例如:蒸奶(Steamed Milk)、豆漿(Soy)、摩卡(Mocha,也就是巧克力風味)或覆蓋奶泡。星巴茲會根據所加入的調料收取不同的費用。所以訂單系統必須考慮到這些調料部分。

           

          二、Decorator模式

           

          1、一個原則

           

          類應該對擴展開放,對修改關閉

           

          2、定義裝飾者模式

          裝飾者模式動態地將責任附加到對象上。若要擴展功能,裝飾者提供了比繼承更有彈性的替代方案。

             

          3.分析任務





          4.設計任務


           

           

          三、代碼實現

           

          1.定義抽象類

           

          1)飲料抽象類Beverage

          Beverage.java

           
          package com.sterning.ch3_decorator;

          /*
           * Beverage是一個抽象類,有兩個方法
           
          */

          public abstract class Beverage {
                  
          public String description="Unknown Beverage";
                  
                  
          /*
                   * getDescription()已經在此實現了,但是cost()必須在子類中實現
                   
          */

                  
          public String getDescription() {
                      
          return description;
                  }

                  
                  
          public abstract double cost();
          }

          2)調料抽象類CondimentDecorator

          CondimentDecorator.java

          package com.sterning.ch3_decorator;

          /*
           * 首先,必須讓CondimentDecorator能夠取代Beverage,所以將CondimentDecorator擴展自Beverage類
           
          */

          public abstract class CondimentDecorator extends Beverage {

              
          //所有的調料裝飾者都必須重新實現getDescription()方法.
              public abstract String getDescription();
          }

           

          2.飲料實現

           

          1Espresso

          Espresso.java

          package com.sterning.ch3_decorator;

          /*
           * 首先,必須讓CondimentDecorator能夠取代Beverage,所以將CondimentDecorator擴展自Beverage類
           
          */

          public abstract class CondimentDecorator extends Beverage {

              
          //所有的調料裝飾者都必須重新實現getDescription()方法.
              public abstract String getDescription();
          }


           

          2HouseBlend

          HouseBlend.java

          package com.sterning.ch3_decorator.drink;

          import com.sterning.ch3_decorator.Beverage;

          public class HouseBlend extends Beverage {
              
              
              
          public HouseBlend() {
                  description
          ="House Blend Coffee";
              }


              @Override
              
          public double cost() {
                  
          return 0.89;
              }


          }

           

          3DarkRoast

          DarkRoast.java

          package com.sterning.ch3_decorator.drink;

          import com.sterning.ch3_decorator.Beverage;

          public class DarkRoast extends Beverage {
              
              
              
          public DarkRoast() {
                  description
          ="Dark Roast Coffee";
              }


              @Override
              
          public double cost() {
                  
          return 0.99;
              }

          }

           

          4Decaf

          Decaf.java

          package com.sterning.ch3_decorator.drink;

          import com.sterning.ch3_decorator.Beverage;

          public class Decaf extends Beverage {
              
              
              
          public Decaf() {
                  description
          ="Decaf Coffee";
              }


              @Override
              
          public double cost() {
                  
          return 1.05;
              }

          }


           

          3.調料實現

          1Mocha

          Mocha.java

          package com.sterning.ch3_decorator.condiment;

          import com.sterning.ch3_decorator.Beverage;
          import com.sterning.ch3_decorator.CondimentDecorator;

          public class Mocha extends CondimentDecorator {
              
          /*
               * 要讓Mocha能夠引用一個Beverage,做法如下:一是用一個實例變量記錄飲料,也就是被裝飾者.
               * 二是想辦法讓裝飾者(飲料)記錄到實例變量中,即把飲料當作構造器的參數,再由構造器將此飲料記錄在實例變量中
               
          */

              Beverage beverage;

              
          public Mocha(Beverage beverage) {
                  
          this.beverage = beverage;
              }


              @Override
              
          public String getDescription() {
                  
          /*
                   * 我們希望敘述不只是描述飲料,而是完整的連調料都描述出來
                   
          */

                  
          return beverage.getDescription()+",Mocha";
              }

                      
              @Override
              
          public double cost() {
                  
          /*
                   * 要計算帶Mocha飲料的價錢,首先把調用委托給裝飾對象,以計算價錢,然后再加上Mocha的價錢,得到最后結果
                   
          */

                  
          return 0.20+beverage.cost();
              }

          }


           

          2Soy

          Soy.java

          package com.sterning.ch3_decorator.condiment;

          import com.sterning.ch3_decorator.Beverage;
          import com.sterning.ch3_decorator.CondimentDecorator;

          public class Soy extends CondimentDecorator {
              Beverage beverage;

              
          public Soy(Beverage beverage) {
                  
          this.beverage = beverage;
              }


              
          public String getDescription() {
                  
          return beverage.getDescription() + ", Soy";
              }


              
          public double cost() {
                  
          return .15 + beverage.cost();
              }

          }


           

          3Whip

          Whip.java

          package com.sterning.ch3_decorator.condiment;

          import com.sterning.ch3_decorator.Beverage;
          import com.sterning.ch3_decorator.CondimentDecorator;
           
          public class Whip extends CondimentDecorator {
              Beverage beverage;
           
              
          public Whip(Beverage beverage) {
                  
          this.beverage = beverage;
              }

           
              
          public String getDescription() {
                  
          return beverage.getDescription() + ", Whip";
              }

           
              
          public double cost() {
                  
          return .10 + beverage.cost();
              }

          }


           

          4.測試類StarbuzzCoffee

          StarbuzzCoffee.java

          package com.sterning.ch3_decorator;

          import com.sterning.ch3_decorator.condiment.Mocha;
          import com.sterning.ch3_decorator.condiment.Soy;
          import com.sterning.ch3_decorator.condiment.Whip;
          import com.sterning.ch3_decorator.drink.DarkRoast;
          import com.sterning.ch3_decorator.drink.Espresso;
          import com.sterning.ch3_decorator.drink.HouseBlend;

          public class StarbuzzCoffee {
              
          public static void main(String args[]){
                  
          /*
                   * 訂一杯Espresso,不需要調料,打印出它的描述和價錢.
                   
          */

                  Beverage beverage
          =new Espresso();
                  System.out.println(beverage.getDescription()
          +" $"+beverage.cost());
                  
                  
          /*
                   * 制造一個DarkRoast對象,用Mocha,Whip裝飾它
                   
          */

                  Beverage beverage2
          =new DarkRoast();
                  beverage2
          =new Mocha(beverage2);
                  beverage2
          =new Mocha(beverage2);
                  beverage2
          =new Whip(beverage2);
                  System.out.println(beverage2.getDescription()
          +" $"+beverage2.cost());    
                  
                  
          /*
                   * 最后,再來一杯調料為豆漿,摩卡\奶泡的HouseBlend咖啡
                   
          */

                  Beverage beverage3
          =new HouseBlend();
                  beverage3
          =new Soy(beverage3);
                  beverage3
          =new Mocha(beverage3);
                  beverage3
          =new Whip(beverage3);
                  System.out.println(beverage3.getDescription()
          +" $"+beverage3.cost());    
              }

          }


          源代碼下載:ch3_decorator.rar

          評論

          # re: 【Head First設計模式】-Decorator模式  回復  更多評論   

          2008-08-01 11:32 by xue
          好,好好

          # re: 【Head First設計模式】-Decorator模式  回復  更多評論   

          2008-08-11 12:08 by zx
          (1)Espresso 代碼貼錯了
          主站蜘蛛池模板: 孟连| 开平市| 永泰县| 镶黄旗| 资阳市| 团风县| 沁源县| 新河县| 文安县| 湖州市| 通化市| 开原市| 黄石市| 吉水县| 黎川县| 古丈县| 浦东新区| 龙川县| 天柱县| 宝兴县| 光山县| 阿荣旗| 民和| 河池市| 芦溪县| 上思县| 津南区| 商丘市| 台南县| 泗水县| 灵山县| 南开区| 托克托县| 齐河县| 赫章县| 任丘市| 滨海县| 涡阳县| 卢湾区| 泗阳县| 偏关县|