<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>

                合規國際互聯網加速 OSASE為企業客戶提供高速穩定SD-WAN國際加速解決方案。 廣告
                在設計原則中有這樣一句話“我們應該針對接口編程,而不是正對實現編程”。但是我們還是在一直使用new關鍵字來創建一個對象,這不就是在針對實現編程么? 針對接口編程,可以隔離掉以后系統可能發生的一大堆改變。如果代碼是針對接口而寫,那么可以通過多態,它可以與任何新類實現該接口。但是,當代碼使用一大堆的具體類時,等于是自找麻煩,因為一旦加入新的具體類,就必須要改變代碼。在這里我們希望能夠調用一個簡單的方法,我傳遞一個參數過去,就可以返回給我一個相應的具體對象,這個時候我們就可以使用簡單工廠模式。 # 引入 1)還沒有工廠時代:假如還沒有工業革命,如果一個客戶要一款寶馬車,一般的做法是客戶去創建一款寶馬車,然后拿來用。 2)簡單工廠模式:后來出現工業革命。用戶不用去創建寶馬車。因為客戶有一個工廠來幫他創建寶馬.想要什么車,這個工廠就可以建。比如想要320i系列車。工廠就創建這個系列的車。即工廠可以創建產品。 3)工廠方法模式時代:為了滿足客戶,寶馬車系列越來越多,如320i,523i,30li等系列一個工廠無法創建所有的寶馬系列。于是由單獨分出來多個具體的工廠。每個具體工廠創建一種系列。即具體工廠類只能創建一個具體產品。但是寶馬工廠還是個抽象。你需要指定某個具體的工廠才能生產車出來。 4)抽象工廠模式時代:隨著客戶的要求越來越高,寶馬車必須配置空調。于是這個工廠開始生產寶馬車和需要的空調。 最終是客戶只要對寶馬的銷售員說:我要523i空調車,銷售員就直接給他523i空調車了。而不用自己去創建523i空調車寶馬車. 這就是工廠模式。 # 分類 工廠模式主要是為創建對象提供過渡接口,以便將創建對象的具體過程屏蔽隔離起來,達到提高靈活性的目的。 工廠模式可以分為三類: 1)簡單工廠模式(Simple Factory) 2)工廠方法模式(Factory Method) 3)抽象工廠模式(Abstract Factory) 這三種模式從上到下逐步抽象,并且更具一般性。 GOF在《設計模式》一書中將工廠模式分為兩類:工廠方法模式(Factory Method)與抽象工廠模式(Abstract Factory)。 > 將簡單工廠模式(Simple Factory)看為工廠方法模式的一種特例,兩者歸為一類。 ## 簡單工廠模式 ### 基本定義 簡單工廠模式又稱之為靜態工廠方法,屬于創建型模式。在簡單工廠模式中,可以根據傳遞的參數不同,返回不同類的實例。簡單工廠模式定義了一個類,這個類專門用于創建其他類的實例,這些被創建的類都有一個共同的父類。 ### 模式結構 ![](https://box.kancloud.cn/df7ec9c40eb8d1dbac45a1d25c8b28cf_414x413.png) ### 組成 * Factory:工廠角色。專門用于創建實例類的工廠,提供一個方法,該方法根據傳遞的參數不同返回不同類的具體實例。 * Product:抽象產品角色。為所有產品的父類。 * ConcreteProduct:具體的產品角色。 簡單工廠模式將對象的創建和對象本身業務處理分離了,可以降低系統的耦合度,使得兩者修改起來都相對容易些。當以后實現改變時,只需要修改工廠類即可。 ### 代碼實現 模式場景:在一個披薩店中,要根據不同客戶的口味,生產不同的披薩,如素食披薩、希臘披薩等披薩。 該例的UML結構圖如下: ![](https://box.kancloud.cn/df027ee852ffa74f635a1fb367176881_699x361.png) Pizza制造工廠:SimplyPizzaFactory.java ~~~ /** * 專門用于創建披薩的工廠類 */ public class SimplePizzaFactory { public Pizza createPizza(String type){ Pizza pizza = null; if(type.equals("cheese")){ pizza = new CheesePizza(); } else if(type.equals("clam")){ pizza = new ClamPizza(); } else if(type.equals("pepperoni")){ pizza = new PepperoniPizza(); } else if(type.equals("veggie")){ pizza = new VeggiePizze(); } return pizza; } } ~~~ 抽象披薩:Pizza.java ~~~ /** * 抽象pizza類 */ public abstract class Pizza { public abstract void prepare(); public abstract void bake(); public abstract void cut(); public abstract void box(); } ~~~ 具體披薩:CheesePizza.java ~~~ public class CheesePizza extends Pizza{ @Override public void bake() { System.out.println("bake CheesePizza ..."); } @Override public void box() { System.out.println("box CheesePizza ..."); } @Override public void cut() { System.out.println("cut CheesePizza ..."); } @Override public void prepare() { System.out.println("prepare CheesePizza ..."); } } ~~~ PizzaStore.java ~~~ public class PizzaStore { SimplePizzaFactory factory; //SimplePizzaFactory的引用 public PizzaStore(SimplePizzaFactory factory){ this.factory = factory; } public Pizza orderPizza(String type){ Pizza pizza; pizza = factory.createPizza(type); //使用工廠對象的創建方法,而不是直接new。這里不再使用具體實例化 pizza.prepare(); pizza.bake(); pizza.cut(); pizza.box(); return pizza; } } ~~~ ### 優點 * 1、簡單工廠模式實現了對責任的分割,提供了專門的工廠類用于創建對象。 * 2、客戶端無須知道所創建的具體產品類的類名,只需要知道具體產品類所對應的參數即可,對于一些復雜的類名,通過簡單工廠模式可以減少使用者的記憶量。 * 3、通過引入配置文件,可以在不修改任何客戶端代碼的情況下更換和增加新的具體產品類,在一定程度上提高了系統的靈活性。 ### 缺點 * 1、由于工廠類集中了所有產品創建邏輯,一旦不能正常工作,整個系統都要受到影響。 * 2、使用簡單工廠模式將會增加系統中類的個數,在一定程序上增加了系統的復雜度和理解難度。 * 3、系統擴展困難,一旦添加新產品就不得不修改工廠邏輯,在產品類型較多時,有可能造成工廠邏輯過于復雜,不利于系統的擴展和維護。 * 4、簡單工廠模式由于使用了靜態工廠方法,造成工廠角色無法形成基于繼承的等級結構。 ### 使用場景 * 1、 工廠類負責創建的對象比較少。 * 2、 客戶端只知道傳入工廠類的參數,對于如何創建對象不關心。 ### 總結 * 1、 簡單工廠模式的要點就在于當你需要什么,只需要傳入一個正確的參數,就可以獲取你所需要的對象,而無須知道其創建細節。 * 2、 簡單工廠模式最大的優點在于實現對象的創建和對象的使用分離,但是如果產品過多時,會導致工廠代碼非常復雜。 ## 工廠方法模式 ### 引入 在披薩實例中,如果我想根據地域的不同生產出不同口味的披薩,如紐約口味披薩,芝加哥口味披薩。如果利用簡單工廠模式,我們需要兩個不同的工廠,NYPizzaFactory、ChicagoPizzaFactory。在該地域中有很多的披薩店,他們并不想依照總店的制作流程來生成披薩,而是希望采用他們自己的制作流程。這個時候如果還使用簡單工廠模式,因為簡單工廠模式是將披薩的制作流程完全承包了。那么怎么辦? 我們可以這樣解決:將披薩的制作方法交給各個披薩店完成,但是他們只能提供制作完成的披薩,披薩的訂單處理仍然要交給披薩工廠去做。也就是說,我們將createPizza()方法放回到PizzaStore中,其他的部分還是保持不變。 ### 基本定義 工廠方法模式定義了一個創建對象的接口,但由子類決定要實例化的類是哪一個。工廠方法模式讓實例化推遲到子類。 ### 模式結構 工廠方法模式的UML結構圖: ![](https://box.kancloud.cn/dbf4e880cd16c9c83b7e1d6e0b57567d_497x323.png) Product:抽象產品。所有的產品必須實現這個共同的接口,這樣一來,使用這些產品的類既可以引用這個接口。而不是具體類。 ConcreteProduct:具體產品。 Creator:抽象工廠。它實現了所有操縱產品的方法,但不實現工廠方法。Creator所有的子類都必須要實現factoryMethod()方法。 ConcreteCreator:具體工廠。制造產品的實際工廠。它負責創建一個或者多個具體產品,只有ConcreteCreator類知道如何創建這些產品。 工廠方法模式是簡單工廠模式的延伸。在工廠方法模式中,核心工廠類不在負責產品的創建,而是將具體的創建工作交給子類去完成。也就是后所這個核心工廠僅僅只是提供創建的接口,具體實現方法交給繼承它的子類去完成。當我們的系統需要增加其他新的對象時,我們只需要添加一個具體的產品和它的創建工廠即可,不需要對原工廠進行任何修改,這樣很好地符合了“開閉原則”。 ### 代碼實現 針對上面的解決方案,得到如下UML結構圖: ![](https://box.kancloud.cn/16ddc455b6b267e7eda26e417f613b48_804x377.png) 抽象產品類:Pizza.java ~~~ public abstract class Pizza { protected String name; //名稱 protected String dough; //面團 protected String sause; //醬料 protected List<String> toppings = new ArrayList<String>(); //佐料 public void prepare() { System.out.println("Preparing "+name); System.out.println("Tossing dough"); System.out.println("Adding sause"); System.out.println("Adding toppings"); for(int i = 0;i < toppings.size();i++){ System.out.println(" "+toppings.get(i)); } } public void bake() { System.out.println("Bake for 25 minutes at 350"); } public void cut() { System.out.println("Cutting the pizza into diagonal slices"); } public void box() { System.out.println("Place pizza in official PizzaStore box"); } public String getName(){ return name; } } ~~~ 具體產品類:NYStyleCheesePizza.java ~~~ public class NYStyleCheesePizza extends Pizza{ public NYStyleCheesePizza(){ name = "Ny Style Sauce and Cheese Pizza"; dough = "Thin Crust Dough"; sause = "Marinara Sauce"; toppings.add("Crated Reggiano Cheese"); } } ~~~ ChicagoStyleCheesePizza.java ~~~ public class ChicagoStyleCheesePizza extends Pizza { public ChicagoStyleCheesePizza(){ name = "Chicago Style Deep Dish Cheese Pizza"; dough = "Extra Thick Crust Dough"; sause = "Plum Tomato Sauce"; toppings.add("Shredded Mozzarella Cheese"); } public void cut(){ System.out.println("Cutting the Pizza into square slices"); } } ~~~ 抽象工廠:披薩總店。PizzaStore.java ~~~ public abstract class PizzaStore { public Pizza orderPizza(String type){ Pizza pizza; pizza = createPizza(type); pizza.prepare(); pizza.bake(); pizza.cut(); pizza.box(); return pizza; } /* * 創建pizza的方法交給子類去實現 */ abstract Pizza createPizza(String type); } ~~~ 具體工廠。披薩分店。NYPizzaStore.java ~~~ public class NYPizzaStore extends PizzaStore{ @Override Pizza createPizza(String item) { Pizza pizza = null; if("cheese".equals(item)){ pizza = new NYStyleCheesePizza(); } else if("veggie".equals(item)){ pizza = new NYStyleVeggiePizza(); } else if("clam".equals(item)){ pizza = new NYStyleClamPizza(); } else if("pepperoni".equals(item)){ pizza = new NYStylePepperoniPizza(); } return pizza; } ~~~ ChicagoPizzaStore.java ~~~ public class ChicagoPizzaStore extends PizzaStore { Pizza createPizza(String type) { Pizza pizza = null; if("cheese".equals(type)){ pizza = new ChicagoStyleCheesePizza(); } else if("clam".equals(type)){ pizza = new ChicagoStyleClamPizza(); } else if("pepperoni".equals(type)) { pizza = new ChicagoStylePepperoniPizza(); } else if("veggie".equals(type)){ pizza = new ChicagoStyleVeggiePizza(); } return pizza; } } ~~~ PizzaTestDrive.java ~~~ public class PizzaTestDrive { public static void main(String[] args) { System.out.println("---------Joel 需要的芝加哥的深盤披薩---------"); ChicagoPizzaStore chicagoPizzaStore = new ChicagoPizzaStore(); //建立芝加哥的披薩店 Pizza joelPizza =chicagoPizzaStore.orderPizza("cheese"); //下訂單 System.out.println("Joel ordered a " + joelPizza.getName() + "\n"); System.out.println("---------Ethan 需要的紐約風味的披薩---------"); NYPizzaStore nyPizzaStore = new NYPizzaStore(); Pizza ethanPizza = nyPizzaStore.orderPizza("cheese"); System.out.println("Ethan ordered a " + ethanPizza.getName() + "\n"); } } ~~~ ### 優點 * 1、 在工廠方法中,用戶只需要知道所要產品的具體工廠,無須關系具體的創建過程,甚至不需要具體產品類的類名。 * 2、 在系統增加新的產品時,我們只需要添加一個具體產品類和對應的實現工廠,無需對原工廠進行任何修改,很好地符合了“開閉原則”。 ### 缺點 * 1、每次增加一個產品時,都需要增加一個具體類和對象實現工廠,是的系統中類的個數成倍增加,在一定程度上增加了系統的復雜度,同時也增加了系統具體類的依賴。這并不是什么好事。 ### 適用場景 * 1、一個類不知道它所需要的對象的類。在工廠方法模式中,我們不需要具體產品的類名,我們只需要知道創建它的具體工廠即可。 * 2、一個類通過其子類來指定創建那個對象。在工廠方法模式中,對于抽象工廠類只需要提供一個創建產品的接口,而由其子類來確定具體要創建的對象,在程序運行時,子類對象將覆蓋父類對象,從而使得系統更容易擴展。 * 3、將創建對象的任務委托給多個工廠子類中的某一個,客戶端在使用時可以無須關心是哪一個工廠子類創建產品子類,需要時再動態指定。 ### 總結 * 1、工廠方法模式完全符合“開閉原則”。 * 2、工廠方法模式使用繼承,將對象的創建委托給子類,通過子類實現工廠方法來創建對象。 * 3、工廠方法允許類將實例化延伸到子類進行。 * 4、工廠方法讓子類決定要實例化的類時哪一個。在這里我們要明白這并不是工廠來決定生成哪種產品,而是在編寫創建者類時,不需要知道實際創建的產品是哪個,選擇了使用哪個子類,就已經決定了實際創建的產品時哪個了。 * 5、在工廠方法模式中,創建者通常會包含依賴于抽象產品的代碼,而這些抽象產品是、由子類創建的,創建者不需要真的知道在制作哪種具體產品。
                  <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>

                              哎呀哎呀视频在线观看