<ruby id="bdb3f"></ruby>

    <p id="bdb3f"><cite id="bdb3f"></cite></p>

      <p id="bdb3f"><cite id="bdb3f"><th id="bdb3f"></th></cite></p><p id="bdb3f"></p>
        <p id="bdb3f"><cite id="bdb3f"></cite></p>

          <pre id="bdb3f"></pre>
          <pre id="bdb3f"><del id="bdb3f"><thead id="bdb3f"></thead></del></pre>

          <ruby id="bdb3f"><mark id="bdb3f"></mark></ruby><ruby id="bdb3f"></ruby>
          <pre id="bdb3f"><pre id="bdb3f"><mark id="bdb3f"></mark></pre></pre><output id="bdb3f"></output><p id="bdb3f"></p><p id="bdb3f"></p>

          <pre id="bdb3f"><del id="bdb3f"><progress id="bdb3f"></progress></del></pre>

                <ruby id="bdb3f"></ruby>

                企業??AI智能體構建引擎,智能編排和調試,一鍵部署,支持知識庫和私有化部署方案 廣告
                本程序改編自《Head First Design Patterns》中的Pizza例子,我本學期早上經常吃包子。 總共有11個類: - 一個工廠父類 ( Creator) - 兩個工廠子類 ( Concrete Creator) - 一個包子父類 ( Product ) - 六個包子子類 ( Concrete Product ) - 一個Main類 ( 程序的入口 ) ![工廠模式](https://box.kancloud.cn/2016-02-22_56cab10c0f37f.jpg "") 圖:ConcreteProduct 繼承 Product,ConcreteCreator 繼承 Creator,ConcreateProduct 依賴 ConcreateProduct。其實,有一條線沒有顯示出來:Creator 依賴 Product。 *Head First* 說,這體現了依賴倒置原則:因為高層模塊(Creator)依賴抽象類(Product),底層模塊(ConcreteProduct)也依賴抽象類(Product)。 補充說明:我個人感覺,嚴格的說:ConcreteProduct 和Product 之間不是依賴,而是繼承關系。勉強說的話,算作一種”非常非常強的依賴“吧。*Head First* : The ConcreteProduct class depends on the Product abstraction too, because they implement the Product interface (we’re using the “interface” in the general sense) in the Product abstraction class. ### 一個工廠父類 ~~~ package factoryMethod; public abstract class BaoZiFactory { // 把具體的 new操作 “下放”到子類中。 abstract BaoZi createBaoZi(String baoZiName); // 這個方法不改變,即無論包子里面的餡是什么,制作包子的流程是一樣的(都是準備餡,然后蒸30分鐘) final public BaoZi makeBaoZi(String baoZiName) { BaoZi baoZi = createBaoZi(baoZiName); baoZi.prepare(); baoZi.steam(); return baoZi; } } ~~~ ### 兩個工廠子類 ~~~ package factoryMethod; public class BaoZiFactoryChangsha extends BaoZiFactory { public BaoZiFactoryChangsha() { System.out.println("Constructor of BaoZiFactory in Changsha\n"); } @Override // 依據傳進來的參數,決定new什么包子 BaoZi createBaoZi(String baoZiName) { BaoZi baoZi = null; if(baoZiName.equals("醬肉")) { baoZi = new ChangshaJiangRouBaoZi(); } else if(baoZiName.equals("青菜")) { baoZi = new ChangshaQingCaiBaoZi(); } else if(baoZiName.equals("鮮肉")) { baoZi = new ChangshaXianRouBaoZi(); } return baoZi; } } ~~~ ~~~ package factoryMethod; public class BaoZiFactoryWuhan extends BaoZiFactory { public BaoZiFactoryWuhan() { System.out.println("Constructor of BaoZiFactory in Wuhan\n"); } @Override // 依據傳進來的參數,決定new什么包子 BaoZi createBaoZi(String baoZiName) { BaoZi baoZi = null; if(baoZiName.equals("醬肉")) { baoZi = new WuhanJiangRouBaoZi(); } else if(baoZiName.equals("青菜")) { baoZi = new WuhanQingCaiBaoZi(); } else if(baoZiName.equals("鮮肉")) { baoZi = new WuhanXianRouBaoZi(); } return baoZi; } } ~~~ ### 一個包子父類 ~~~ package factoryMethod; import java.util.ArrayList; // 父類:包子,抽象出包子共有的特性 // 有道詞典:steamed stuffed bun (蒸的,填充的,小圓面包) // 由于這三個單詞加起來過長,我命名放棄采納英文命名法,直接使用漢語拼音命名法BaoZi public abstract class BaoZi { private String name; ArrayList<String> stuffings = new ArrayList<String> (); public void setName(String n) { this.name = n; } public String getName() { return name; } void prepare() { System.out.println("Prepare " + name); System.out.println("Stuffings are:"); for(String stuff: stuffings) { System.out.println(stuff); } } void steam() { System.out.println("Steam for 30 minutes"); } //覆蓋toString (這個方法繼承自java.lang.Object) public String toString() { StringBuffer display = new StringBuffer(); display.append("---- " + name + " ----\n"); for(String stuff : stuffings) { display.append(stuff + "\n"); } return display.toString(); } } ~~~ ### 六個包子子類 ~~~ package factoryMethod; public class ChangshaJiangRouBaoZi extends BaoZi { public ChangshaJiangRouBaoZi() { setName("長沙醬肉包子"); stuffings.add("辣椒"); stuffings.add("炸醬"); stuffings.add("肉末"); stuffings.add("干子"); } } ~~~ ~~~ package factoryMethod; public class ChangshaQingCaiBaoZi extends BaoZi { public ChangshaQingCaiBaoZi() { setName("長沙青菜包子"); stuffings.add("辣椒"); stuffings.add("包菜"); stuffings.add("茄子"); } } ~~~ ~~~ package factoryMethod; public class ChangshaXianRouBaoZi extends BaoZi { public ChangshaXianRouBaoZi() { setName("長沙鮮肉包子"); stuffings.add("辣椒"); stuffings.add("鮮肉"); } } ~~~ ~~~ package factoryMethod; public class WuhanJiangRouBaoZi extends BaoZi { public WuhanJiangRouBaoZi() { setName("武漢醬肉包子"); stuffings.add("炸醬"); stuffings.add("肉末"); stuffings.add("干子"); } } ~~~ ~~~ package factoryMethod; public class WuhanQingCaiBaoZi extends BaoZi { public WuhanQingCaiBaoZi() { setName("武漢青菜包子"); stuffings.add("包菜"); stuffings.add("茄子"); } } ~~~ ~~~ package factoryMethod; public class WuhanXianRouBaoZi extends BaoZi { public WuhanXianRouBaoZi() { setName("武漢鮮肉包子"); stuffings.add("鮮肉"); } } ~~~ ### 一個Main類 ~~~ package factoryMethod; public class Main { public static void main(String[] args) { BaoZiFactory wuhanFactory = new BaoZiFactoryWuhan(); BaoZiFactory changshaFactory = new BaoZiFactoryChangsha(); BaoZi baoZi = null; baoZi = wuhanFactory.makeBaoZi("醬肉"); System.out.println("Caitao made a " + baoZi.getName() + "\n"); baoZi = wuhanFactory.makeBaoZi("青菜"); System.out.println("Caitao made a " + baoZi.getName() + "\n"); baoZi = changshaFactory.makeBaoZi("鮮肉"); System.out.println("Lucy made a " + baoZi.getName() + "\n"); baoZi = changshaFactory.makeBaoZi("青菜"); System.out.println("Lucy made a " + baoZi.getName() + "\n"); } } ~~~ ### 運行結果 直接從eclipse復制過來的 ~~~ Constructor of BaoZiFactory in Wuhan Constructor of BaoZiFactory in Changsha Prepare 武漢醬肉包子 Stuffings are: 炸醬 肉末 干子 Steam for 30 minutes Caitao made a 武漢醬肉包子 Prepare 武漢青菜包子 Stuffings are: 包菜 茄子 Steam for 30 minutes Caitao made a 武漢青菜包子 Prepare 長沙鮮肉包子 Stuffings are: 辣椒 鮮肉 Steam for 30 minutes Lucy made a 長沙鮮肉包子 Prepare 長沙青菜包子 Stuffings are: 辣椒 包菜 茄子 Steam for 30 minutes Lucy made a 長沙青菜包子 ~~~ ### 如果沒有工廠方法模式 又要實現同樣的功能怎么破?代碼如下(理想輸入條件,沒有異常處理) ~~~ public BaoZi makeBaoZi(String place, String type) { BaoZi baoZi = null; if (place.equals("武漢")) { if (type.equals("醬肉")) { baoZi = new WuhanJiangRouBaoZi(); } else if (type.equals("青菜")) { baoZi = new WuhanQingCaiBaoZi(); } else if (type.equals("鮮肉")) { baoZi = new WuhanXianRouBaoZi(); } } else if (place.equals("長沙")) { if (type.equals("醬肉")) { baoZi = new ChangshaJiangRouBaoZi(); } else if (type.equals("青菜")) { baoZi = new ChangshaQingCaiBaoZi(); } else if (type.equals("鮮肉")) { baoZi = new ChangshaXianRouBaoZi(); } } baoZi.prepare(); baoZi.steam(); return baoZi; } ~~~ ~~~ 優劣之分立馬體現出來了!我們可以看到代碼變短了(當然了,需要增加一些類作為“額外工作”,這是值得的) 創建包子的new操作“隱藏了”,取而代之的是一個factory對象調用createBaoZi方法 public BaoZi makeBaoZi(String place, String type) { BaoZiFactory factory = null; if(place.equals("武漢")) { factory = new BaoZiFactoryWuhan(); } else if(place.equals("長沙")) { factory = new BaoZiFactoryChangsha(); } BaoZi baoZi = factory.createBaoZi(type); baoZi.prepare(); baoZi.steam(); return baoZi; } ~~~ **1. 工廠方法模式的優勢**:如果位于武漢的工廠需要增加一種口味的包子(這種類似的事情經常發生),比如”熱干包子“,那么工廠方法模式只用增加一個包子子類,然后修改武漢工廠子類就行了。 ~~~ 關鍵是下面的代碼不變,放到哪里都一樣,以不變應萬變! BaoZiFactory factory = null; if(place.equals("武漢")) { factory = new BaoZiFactoryWuhan(); } else if(place.equals("長沙")) { factory = new BaoZiFactoryChangsha(); } BaoZi baoZi = factory.createBaoZi(type); ~~~ **2. 沒有工廠方法模式的劣勢**:如果位于武漢的工廠需要增加一種口味的包子(這種類似的事情經常發生),比如”熱干包子“,那么所有用于在武漢創建包子的 if( … ) { new … } else( ) { … } 的代碼都在后面增加一個 if( 熱干 ) {new ReGanBaoZiWuhan() } else( ) { … } ~~~ BaoZi baoZi = null; if (place.equals("武漢")) { if (type.equals("醬肉")) { baoZi = new WuhanJiangRouBaoZi(); } else if (type.equals("青菜")) { baoZi = new WuhanQingCaiBaoZi(); } else if (type.equals("鮮肉")) { baoZi = new WuhanXianRouBaoZi(); } *********增加的代碼***************** else if(type.equals("熱干")) { baoZi = new WuhanReGanBaoZi(); } ************************************ } else if (place.equals("長沙")) { if (type.equals("醬肉")) { baoZi = new ChangshaJiangRouBaoZi(); } else if (type.equals("青菜")) { baoZi = new ChangshaQingCaiBaoZi(); } else if (type.equals("鮮肉")) { baoZi = new ChangshaXianRouBaoZi(); } } ~~~ 改一個地方還比較輕松,**但是關鍵在于很有可能在很多地方都要用到包子**。假設100個地方都要創建包子,那么100個地方的if( … )else( )“的代碼都要修改!這完全是反人類,違反了開閉原則。 [更多深入分析,查看我的這一篇博客,進入目錄->第三個標題](http://blog.csdn.net/u013390476/article/details/50333763)
                  <ruby id="bdb3f"></ruby>

                  <p id="bdb3f"><cite id="bdb3f"></cite></p>

                    <p id="bdb3f"><cite id="bdb3f"><th id="bdb3f"></th></cite></p><p id="bdb3f"></p>
                      <p id="bdb3f"><cite id="bdb3f"></cite></p>

                        <pre id="bdb3f"></pre>
                        <pre id="bdb3f"><del id="bdb3f"><thead id="bdb3f"></thead></del></pre>

                        <ruby id="bdb3f"><mark id="bdb3f"></mark></ruby><ruby id="bdb3f"></ruby>
                        <pre id="bdb3f"><pre id="bdb3f"><mark id="bdb3f"></mark></pre></pre><output id="bdb3f"></output><p id="bdb3f"></p><p id="bdb3f"></p>

                        <pre id="bdb3f"><del id="bdb3f"><progress id="bdb3f"></progress></del></pre>

                              <ruby id="bdb3f"></ruby>

                              哎呀哎呀视频在线观看