JAVA 設計模式系列——工廠模式

{"type":"doc","content":[{"type":"heading","attrs":{"align":null,"level":1}},{"type":"paragraph","attrs":{"indent":0,"number":0,"align":null,"origin":null},"content":[{"type":"text","text":"軟件設計模式(Software Design Pattern),又稱","attrs":{}},{"type":"text","marks":[{"type":"strong","attrs":{}}],"text":"設計模式","attrs":{}},{"type":"text","text":",是一套被反覆使用、多數人知曉的、經過分類編目的、代碼設計經驗的總結。它描述了在軟件設計過程中的一些不斷重複發生的問題,以及該問題的解決方案。","attrs":{}}]},{"type":"paragraph","attrs":{"indent":0,"number":0,"align":null,"origin":null}},{"type":"paragraph","attrs":{"indent":0,"number":0,"align":null,"origin":null},"content":[{"type":"text","text":"也就是說,它是解決特定問題的一系列套路,是前輩們的代碼設計經驗的總結,具有一定的普遍性,可以反覆使用。","attrs":{}}]},{"type":"paragraph","attrs":{"indent":0,"number":0,"align":null,"origin":null}},{"type":"paragraph","attrs":{"indent":0,"number":0,"align":null,"origin":null},"content":[{"type":"text","text":"其目的是爲了提高代碼的可重用性、代碼的可讀性和代碼的可靠性。","attrs":{}}]},{"type":"paragraph","attrs":{"indent":0,"number":0,"align":null,"origin":null}},{"type":"paragraph","attrs":{"indent":0,"number":0,"align":null,"origin":null},"content":[{"type":"text","text":"那麼我們今天來看看設計模式中的第二種工廠模式中的","attrs":{}},{"type":"text","marks":[{"type":"strong","attrs":{}}],"text":"工廠方法模式","attrs":{}},{"type":"text","text":"。","attrs":{}}]},{"type":"paragraph","attrs":{"indent":0,"number":0,"align":null,"origin":null}},{"type":"image","attrs":{"src":"https://static001.geekbang.org/infoq/b1/b1e95fa7012e2a44cbe29af16610a747.png","alt":null,"title":null,"style":[{"key":"width","value":"75%"},{"key":"bordertype","value":"none"}],"href":null,"fromPaste":true,"pastePass":true}},{"type":"paragraph","attrs":{"indent":0,"number":0,"align":null,"origin":null}},{"type":"paragraph","attrs":{"indent":0,"number":0,"align":null,"origin":null},"content":[{"type":"text","text":"在現實生活中社會分工越來越細,越來越專業化,各種產品有專門的工廠生產,徹底告別了自給自足的小農經濟時代,這大大縮短了產品的生產週期,提高了生產效率。那麼我們可能會考慮在軟件開發中能否做到軟件對象的生產和使用相分離呢?而這便需要我們的設計模式中的","attrs":{}},{"type":"text","marks":[{"type":"strong","attrs":{}}],"text":"工廠模式","attrs":{}},{"type":"text","text":"。","attrs":{}}]},{"type":"paragraph","attrs":{"indent":0,"number":0,"align":null,"origin":null}},{"type":"paragraph","attrs":{"indent":0,"number":0,"align":null,"origin":null},"content":[{"type":"text","text":"首先我們來回想一下,社會由最開始的自給自足原始社會,到農耕小作坊時代,到工業革命流水線,再到現代產業鏈代工廠,我們會發現生產的效率越來越高,其實整個社會的進步就是工廠模式發展的縮影。最開始自給自足是沒有工廠;到小作坊簡單完成商品的生產,爲簡單工廠模式;到工業革命流水線,商品完成自產自銷,爲工廠方法模式;到現階段產業鏈代工廠,如現在的富士康等企業,爲其他企業提供工廠流水線,爲","attrs":{}},{"type":"text","marks":[{"type":"strong","attrs":{}}],"text":"抽象工廠模式","attrs":{}},{"type":"text","text":"。","attrs":{}}]},{"type":"paragraph","attrs":{"indent":0,"number":0,"align":null,"origin":null}},{"type":"paragraph","attrs":{"indent":0,"number":0,"align":null,"origin":null},"content":[{"type":"text","marks":[{"type":"strong","attrs":{}}],"text":"什麼是工廠模式呢?","attrs":{}}]},{"type":"paragraph","attrs":{"indent":0,"number":0,"align":null,"origin":null}},{"type":"paragraph","attrs":{"indent":0,"number":0,"align":null,"origin":null},"content":[{"type":"text","text":"定義一個創建產品對象的工廠接口,將產品對象的實際創建工作推遲到具體子工廠類當中。這滿足創建型模式中所要求的“創建與使用相分離”的特點。所有我們在實際開發中,凡是需要生成複雜對象的地方,都可以嘗試考慮使用工廠模式來代替。而按實際業務場景劃分,工廠模式有 3 種不同的實現方式,分別是簡單工廠模式、工廠方法模式和抽象工廠模式。","attrs":{}}]},{"type":"paragraph","attrs":{"indent":0,"number":0,"align":null,"origin":null}},{"type":"paragraph","attrs":{"indent":0,"number":0,"align":null,"origin":null},"content":[{"type":"text","text":"所以緊接着我們來依次根據不同的場景看看這幾種工廠模式。","attrs":{}}]},{"type":"heading","attrs":{"align":null,"level":5},"content":[{"type":"text","marks":[{"type":"strong","attrs":{}}],"text":"簡單工廠模式","attrs":{}}]},{"type":"paragraph","attrs":{"indent":0,"number":0,"align":null,"origin":null},"content":[{"type":"text","text":"我們把被創建的對象稱爲“產品”,把創建產品的對象稱爲“工廠”。如果要創建的產品不多,只要一個工廠類就可以完成,這種模式叫**“簡單工廠模式”**。","attrs":{}}]},{"type":"paragraph","attrs":{"indent":0,"number":0,"align":null,"origin":null}},{"type":"paragraph","attrs":{"indent":0,"number":0,"align":null,"origin":null},"content":[{"type":"text","text":"在簡單工廠模式中創建實例的方法通常爲","attrs":{}},{"type":"text","marks":[{"type":"strong","attrs":{}}],"text":"靜態(static)方法","attrs":{}}]},{"type":"paragraph","attrs":{"indent":0,"number":0,"align":null,"origin":null}},{"type":"paragraph","attrs":{"indent":0,"number":0,"align":null,"origin":null},"content":[{"type":"text","text":"因此簡單工廠模式(Simple Factory Pattern)又叫作","attrs":{}},{"type":"text","marks":[{"type":"strong","attrs":{}}],"text":"靜態工廠方法模式","attrs":{}},{"type":"text","text":"(Static Factory Method Pattern)。","attrs":{}}]},{"type":"paragraph","attrs":{"indent":0,"number":0,"align":null,"origin":null}},{"type":"paragraph","attrs":{"indent":0,"number":0,"align":null,"origin":null},"content":[{"type":"text","marks":[{"type":"strong","attrs":{}}],"text":"首先我們來看看簡單工廠模式的組成:","attrs":{}}]},{"type":"paragraph","attrs":{"indent":0,"number":0,"align":null,"origin":null}},{"type":"bulletedlist","content":[{"type":"listitem","attrs":{"listStyle":null},"content":[{"type":"paragraph","attrs":{"indent":0,"number":0,"align":null,"origin":null},"content":[{"type":"text","text":"簡單工廠(SimpleFactory):是簡單工廠模式的核心,負責實現創建所有實例的內部邏輯。工廠類的創建產品類的方法可以被外界直接調用,創建所需的產品對象。","attrs":{}}]}]},{"type":"listitem","attrs":{"listStyle":null},"content":[{"type":"paragraph","attrs":{"indent":0,"number":0,"align":null,"origin":null},"content":[{"type":"text","text":"抽象產品(Product):是簡單工廠創建的所有對象的父類,負責描述所有實例共有的公共接口。","attrs":{}}]}]},{"type":"listitem","attrs":{"listStyle":null},"content":[{"type":"paragraph","attrs":{"indent":0,"number":0,"align":null,"origin":null},"content":[{"type":"text","text":"具體產品(ConcreteProduct):是簡單工廠模式的創建目標。","attrs":{}}]}]}],"attrs":{}},{"type":"paragraph","attrs":{"indent":0,"number":0,"align":null,"origin":null}},{"type":"paragraph","attrs":{"indent":0,"number":0,"align":null,"origin":null},"content":[{"type":"text","text":"繪製結構圖如下:","attrs":{}}]},{"type":"paragraph","attrs":{"indent":0,"number":0,"align":null,"origin":null}},{"type":"image","attrs":{"src":"https://static001.geekbang.org/infoq/ed/ed0ed8f925ec9d27ac83a1d7263dbdb8.png","alt":null,"title":null,"style":[{"key":"width","value":"75%"},{"key":"bordertype","value":"none"}],"href":null,"fromPaste":true,"pastePass":true}},{"type":"paragraph","attrs":{"indent":0,"number":0,"align":null,"origin":null}},{"type":"paragraph","attrs":{"indent":0,"number":0,"align":null,"origin":null}},{"type":"paragraph","attrs":{"indent":0,"number":0,"align":null,"origin":null},"content":[{"type":"text","text":"​\t\t\t\t\t\t\t\t\t\t\t\t\t\t\t\t\t\t圖-1 簡單工廠模式結構圖","attrs":{}}]},{"type":"paragraph","attrs":{"indent":0,"number":0,"align":null,"origin":null}},{"type":"paragraph","attrs":{"indent":0,"number":0,"align":null,"origin":null},"content":[{"type":"text","marks":[{"type":"strong","attrs":{}}],"text":"如果我們用java代碼表示是怎樣的呢?","attrs":{}}]},{"type":"paragraph","attrs":{"indent":0,"number":0,"align":null,"origin":null}},{"type":"codeblock","attrs":{"lang":"java"},"content":[{"type":"text","text":"/**\n * @author hz\n * @version 1.0\n */\npublic class Client {\n //抽象產品\n public interface Product {\n void show();\n }\n //具體產品:ProductA\n static class ConcreteProduct1 implements Product {\n public void show() {\n System.out.println(\"具體產品1顯示...\");\n }\n }\n //具體產品:ProductB\n static class ConcreteProduct2 implements Product {\n public void show() {\n System.out.println(\"具體產品2顯示...\");\n }\n }\n final class Const {\n static final int PRODUCT_A = 0;\n static final int PRODUCT_B = 1;\n static final int PRODUCT_C = 2;\n }\n static class SimpleFactory {\n public static Product makeProduct(int kind) {\n switch (kind) {\n case Const.PRODUCT_A:\n return new ConcreteProduct1();\n case Const.PRODUCT_B:\n return new ConcreteProduct2();\n }\n return null;\n }\n }\n}\n","attrs":{}}]},{"type":"paragraph","attrs":{"indent":0,"number":0,"align":null,"origin":null}},{"type":"paragraph","attrs":{"indent":0,"number":0,"align":null,"origin":null},"content":[{"type":"text","marks":[{"type":"strong","attrs":{}}],"text":"該模式的優缺點有哪些呢?","attrs":{}}]},{"type":"paragraph","attrs":{"indent":0,"number":0,"align":null,"origin":null}},{"type":"paragraph","attrs":{"indent":0,"number":0,"align":null,"origin":null},"content":[{"type":"text","text":"優點:","attrs":{}}]},{"type":"paragraph","attrs":{"indent":0,"number":0,"align":null,"origin":null}},{"type":"numberedlist","attrs":{"start":1,"normalizeStart":1},"content":[{"type":"listitem","attrs":{"listStyle":null},"content":[{"type":"paragraph","attrs":{"indent":0,"number":1,"align":null,"origin":null},"content":[{"type":"text","text":"工廠類包含必要的邏輯判斷,可以決定在什麼時候創建哪一個產品的實例。客戶端可以免除直接創建產品對象的職責,很方便的創建出相應的產品。工廠和產品的職責區分明確。","attrs":{}}]}]},{"type":"listitem","attrs":{"listStyle":null},"content":[{"type":"paragraph","attrs":{"indent":0,"number":2,"align":null,"origin":null},"content":[{"type":"text","text":"客戶端無需知道所創建具體產品的類名,只需知道參數即可。","attrs":{}}]}]},{"type":"listitem","attrs":{"listStyle":null},"content":[{"type":"paragraph","attrs":{"indent":0,"number":3,"align":null,"origin":null},"content":[{"type":"text","text":"也可以引入配置文件,在不修改客戶端代碼的情況下更換和添加新的具體產品類。","attrs":{}}]}]}]},{"type":"paragraph","attrs":{"indent":0,"number":0,"align":null,"origin":null}},{"type":"paragraph","attrs":{"indent":0,"number":0,"align":null,"origin":null},"content":[{"type":"text","text":"缺點:","attrs":{}}]},{"type":"paragraph","attrs":{"indent":0,"number":0,"align":null,"origin":null}},{"type":"numberedlist","attrs":{"start":1,"normalizeStart":1},"content":[{"type":"listitem","attrs":{"listStyle":null},"content":[{"type":"paragraph","attrs":{"indent":0,"number":1,"align":null,"origin":null},"content":[{"type":"text","text":"簡單工廠模式的工廠類單一,負責所有產品的創建,職責過重,一旦異常,整個系統將受影響。且工廠類代碼會非常臃腫,違背高聚合原則。","attrs":{}}]}]},{"type":"listitem","attrs":{"listStyle":null},"content":[{"type":"paragraph","attrs":{"indent":0,"number":2,"align":null,"origin":null},"content":[{"type":"text","text":"使用簡單工廠模式會增加系統中類的個數(引入新的工廠類),增加系統的複雜度和理解難度","attrs":{}}]}]},{"type":"listitem","attrs":{"listStyle":null},"content":[{"type":"paragraph","attrs":{"indent":0,"number":3,"align":null,"origin":null},"content":[{"type":"text","text":"系統擴展困難,一旦增加新產品不得不修改工廠邏輯,在產品類型較多時,可能造成邏輯過於複雜","attrs":{}}]}]},{"type":"listitem","attrs":{"listStyle":null},"content":[{"type":"paragraph","attrs":{"indent":0,"number":4,"align":null,"origin":null},"content":[{"type":"text","text":"簡單工廠模式使用了 static 工廠方法,造成工廠角色無法形成基於繼承的等級結構。","attrs":{}}]}]}]},{"type":"paragraph","attrs":{"indent":0,"number":0,"align":null,"origin":null}},{"type":"paragraph","attrs":{"indent":0,"number":0,"align":null,"origin":null},"content":[{"type":"text","text":"但是簡單工廠模式每增加一個產品就要增加一個具體產品類和一個對應的具體工廠類,這增加了系統的複雜度,違背了**“開閉原則”**,因此我們進行進一步對簡單工廠進行抽象,這個也是我們後面馬上將給大家說的工廠模式的第二個實現場景,工廠方法模式。","attrs":{}}]},{"type":"heading","attrs":{"align":null,"level":4},"content":[{"type":"text","marks":[{"type":"strong","attrs":{}}],"text":"工廠方法模式","attrs":{}}]},{"type":"paragraph","attrs":{"indent":0,"number":0,"align":null,"origin":null},"content":[{"type":"text","text":"前面我們說了簡單工廠模式違背了開閉原則,而“工廠方法模式”是對簡單工廠模式的進一步抽象化,其好處是可以使系統在不修改原來代碼的情況下引進新的產品,即滿足開閉原則。","attrs":{}}]},{"type":"paragraph","attrs":{"indent":0,"number":0,"align":null,"origin":null}},{"type":"paragraph","attrs":{"indent":0,"number":0,"align":null,"origin":null},"content":[{"type":"text","marks":[{"type":"strong","attrs":{}}],"text":"工廠方法模式的主要角色包含:","attrs":{}}]},{"type":"paragraph","attrs":{"indent":0,"number":0,"align":null,"origin":null}},{"type":"bulletedlist","content":[{"type":"listitem","attrs":{"listStyle":null},"content":[{"type":"paragraph","attrs":{"indent":0,"number":0,"align":null,"origin":null},"content":[{"type":"text","text":"抽象工廠(Abstract Factory):提供了創建產品的接口,調用者通過它訪問具體工廠的工廠方法 newProduct() 來創建產品。","attrs":{}}]}]},{"type":"listitem","attrs":{"listStyle":null},"content":[{"type":"paragraph","attrs":{"indent":0,"number":0,"align":null,"origin":null},"content":[{"type":"text","text":"具體工廠(ConcreteFactory):主要是實現抽象工廠中的抽象方法,完成具體產品的創建。","attrs":{}}]}]},{"type":"listitem","attrs":{"listStyle":null},"content":[{"type":"paragraph","attrs":{"indent":0,"number":0,"align":null,"origin":null},"content":[{"type":"text","text":"抽象產品(Product):定義了產品的規範,描述了產品的主要特性和功能。","attrs":{}}]}]},{"type":"listitem","attrs":{"listStyle":null},"content":[{"type":"paragraph","attrs":{"indent":0,"number":0,"align":null,"origin":null},"content":[{"type":"text","text":"具體產品(ConcreteProduct):實現了抽象產品角色所定義的接口,由具體工廠來創建,它同具體工廠之間一一對應。","attrs":{}}]}]}],"attrs":{}},{"type":"paragraph","attrs":{"indent":0,"number":0,"align":null,"origin":null}},{"type":"paragraph","attrs":{"indent":0,"number":0,"align":null,"origin":null},"content":[{"type":"text","marks":[{"type":"strong","attrs":{}}],"text":"繪製結構圖如下:","attrs":{}}]},{"type":"paragraph","attrs":{"indent":0,"number":0,"align":null,"origin":null}},{"type":"image","attrs":{"src":"https://static001.geekbang.org/infoq/3a/3ae26b6bdd8de9d5dd1a70d81326621e.png","alt":null,"title":null,"style":[{"key":"width","value":"75%"},{"key":"bordertype","value":"none"}],"href":null,"fromPaste":true,"pastePass":true}},{"type":"paragraph","attrs":{"indent":0,"number":0,"align":null,"origin":null}},{"type":"paragraph","attrs":{"indent":0,"number":0,"align":null,"origin":null}},{"type":"paragraph","attrs":{"indent":0,"number":0,"align":null,"origin":null},"content":[{"type":"text","text":"​\t\t\t\t\t\t\t\t\t\t\t\t\t\t\t\t\t ","attrs":{}}]},{"type":"paragraph","attrs":{"indent":0,"number":0,"align":null,"origin":null}},{"type":"paragraph","attrs":{"indent":0,"number":0,"align":null,"origin":null},"content":[{"type":"text","text":"對比簡單工廠模式,工廠方法模式在之間簡單的工廠的基礎之上將工廠進行拆分成抽象工廠和具體工廠兩部分內容,這樣靈活性得到大量提升。","attrs":{}}]},{"type":"paragraph","attrs":{"indent":0,"number":0,"align":null,"origin":null}},{"type":"paragraph","attrs":{"indent":0,"number":0,"align":null,"origin":null},"content":[{"type":"text","marks":[{"type":"strong","attrs":{}}],"text":"而這種模式我們可以在那些場合使用呢?","attrs":{}}]},{"type":"paragraph","attrs":{"indent":0,"number":0,"align":null,"origin":null}},{"type":"bulletedlist","content":[{"type":"listitem","attrs":{"listStyle":null},"content":[{"type":"paragraph","attrs":{"indent":0,"number":0,"align":null,"origin":null},"content":[{"type":"text","text":"用戶只需要知道具體工廠的名稱就可得到所要的產品,無須知道產品的具體創建過程。","attrs":{}}]}]},{"type":"listitem","attrs":{"listStyle":null},"content":[{"type":"paragraph","attrs":{"indent":0,"number":0,"align":null,"origin":null},"content":[{"type":"text","text":"靈活性增強,對於新產品的創建,只需多寫一個相應的工廠類。","attrs":{}}]}]},{"type":"listitem","attrs":{"listStyle":null},"content":[{"type":"paragraph","attrs":{"indent":0,"number":0,"align":null,"origin":null},"content":[{"type":"text","text":"典型的解耦框架。高層模塊只需要知道產品的抽象類,無須關心其他實現類,滿足迪米特法則、依賴倒置原則和里氏替換原則。","attrs":{}}]}]}],"attrs":{}},{"type":"paragraph","attrs":{"indent":0,"number":0,"align":null,"origin":null}},{"type":"paragraph","attrs":{"indent":0,"number":0,"align":null,"origin":null},"content":[{"type":"text","marks":[{"type":"strong","attrs":{}}],"text":"如果我們用java代碼表示是怎樣的呢?","attrs":{}}]},{"type":"paragraph","attrs":{"indent":0,"number":0,"align":null,"origin":null}},{"type":"codeblock","attrs":{"lang":"java"},"content":[{"type":"text","text":"/**\n * @author hz\n * @version 1.0\n */\npublic class AbstractFactoryTest {\n public static void main(String[] args) {\n try {\n Product a;\n AbstractFactory af;\n af = (AbstractFactory) ReadXML.getObject();\n //抽象工廠內容放入到外部配置文件xml/properties等文件中,通過I/O流加載從而創建出抽象工廠\n a = af.newProduct();\n a.show();\n } catch (Exception e) {\n System.out.println(e.getMessage());\n }\n }\n}\n//抽象產品:提供了產品的接口\ninterface Product {\n public void show();\n}\n//具體產品1:實現抽象產品中的抽象方法\nclass ConcreteProduct1 implements Product {\n public void show() {\n System.out.println(\"具體產品1顯示...\");\n }\n}\n//具體產品2:實現抽象產品中的抽象方法\nclass ConcreteProduct2 implements Product {\n public void show() {\n System.out.println(\"具體產品2顯示...\");\n }\n}\n//抽象工廠:提供了廠品的生成方法\ninterface AbstractFactory {\n public Product newProduct();\n}\n//具體工廠1:實現了廠品的生成方法\nclass ConcreteFactory1 implements AbstractFactory {\n public Product newProduct() {\n System.out.println(\"具體工廠1生成-->具體產品1...\");\n return new ConcreteProduct1();\n }\n}\n//具體工廠2:實現了廠品的生成方法\nclass ConcreteFactory2 implements AbstractFactory {\n public Product newProduct() {\n System.out.println(\"具體工廠2生成-->具體產品2...\");\n return new ConcreteProduct2();\n }\n}\n","attrs":{}}]},{"type":"paragraph","attrs":{"indent":0,"number":0,"align":null,"origin":null}},{"type":"codeblock","attrs":{"lang":"java"},"content":[{"type":"text","text":"import javax.xml.parsers.*;\nimport org.w3c.dom.*;\nimport java.io.*;\n/**\n * @author hz\n * @version 1.0\n */\npublic class ReadXML {\n //該方法用於從XML配置文件中提取具體類類名,並返回一個實例對象\n public static Object getObject() {\n try {\n //創建文檔對象\n DocumentBuilderFactory dFactory = DocumentBuilderFactory.newInstance();\n DocumentBuilder builder = dFactory.newDocumentBuilder();\n Document doc;\n doc = builder.parse(new File(\"src/FactoryMethod/config1.xml\"));\n //獲取包含類名的文本節點\n NodeList nl = doc.getElementsByTagName(\"className\");\n Node classNode = nl.item(0).getFirstChild();\n String cName = \"FactoryMethod.\" + classNode.getNodeValue();\n //System.out.println(\"新類名:\"+cName);\n //通過類名生成實例對象並將其返回\n Class> c = Class.forName(cName);\n Object obj = c.newInstance();\n return obj;\n } catch (Exception e) {\n e.printStackTrace();\n return null;\n }\n }\n\n}\n","attrs":{}}]},{"type":"paragraph","attrs":{"indent":0,"number":0,"align":null,"origin":null}},{"type":"paragraph","attrs":{"indent":0,"number":0,"align":null,"origin":null},"content":[{"type":"text","marks":[{"type":"strong","attrs":{}}],"text":"那麼該模式有哪些優缺點呢?","attrs":{}}]},{"type":"paragraph","attrs":{"indent":0,"number":0,"align":null,"origin":null}},{"type":"paragraph","attrs":{"indent":0,"number":0,"align":null,"origin":null},"content":[{"type":"text","text":"優點:","attrs":{}}]},{"type":"paragraph","attrs":{"indent":0,"number":0,"align":null,"origin":null}},{"type":"bulletedlist","content":[{"type":"listitem","attrs":{"listStyle":null},"content":[{"type":"paragraph","attrs":{"indent":0,"number":0,"align":null,"origin":null},"content":[{"type":"text","text":"用戶只需要知道具體工廠的名稱就可得到所要的產品,無須知道產品的具體創建過程。","attrs":{}}]}]},{"type":"listitem","attrs":{"listStyle":null},"content":[{"type":"paragraph","attrs":{"indent":0,"number":0,"align":null,"origin":null},"content":[{"type":"text","text":"靈活性增強,對於新產品的創建,只需多寫一個相應的工廠類。","attrs":{}}]}]},{"type":"listitem","attrs":{"listStyle":null},"content":[{"type":"paragraph","attrs":{"indent":0,"number":0,"align":null,"origin":null},"content":[{"type":"text","text":"典型的解耦框架。高層模塊只需要知道產品的抽象類,無須關心其他實現類,滿足迪米特法則、依賴倒置原則和里氏替換原則。","attrs":{}}]}]}],"attrs":{}},{"type":"paragraph","attrs":{"indent":0,"number":0,"align":null,"origin":null}},{"type":"paragraph","attrs":{"indent":0,"number":0,"align":null,"origin":null},"content":[{"type":"text","text":"缺點:","attrs":{}}]},{"type":"paragraph","attrs":{"indent":0,"number":0,"align":null,"origin":null}},{"type":"bulletedlist","content":[{"type":"listitem","attrs":{"listStyle":null},"content":[{"type":"paragraph","attrs":{"indent":0,"number":0,"align":null,"origin":null},"content":[{"type":"text","text":"類的個數容易過多,增加複雜度","attrs":{}}]}]},{"type":"listitem","attrs":{"listStyle":null},"content":[{"type":"paragraph","attrs":{"indent":0,"number":0,"align":null,"origin":null},"content":[{"type":"text","text":"增加了系統的抽象性和理解難度","attrs":{}}]}]},{"type":"listitem","attrs":{"listStyle":null},"content":[{"type":"paragraph","attrs":{"indent":0,"number":0,"align":null,"origin":null},"content":[{"type":"text","text":"抽象產品只能生產一種產品,此弊端可使用抽象工廠模式解決。","attrs":{}}]}]}],"attrs":{}},{"type":"paragraph","attrs":{"indent":0,"number":0,"align":null,"origin":null}},{"type":"image","attrs":{"src":"https://static001.geekbang.org/infoq/b1/b1e95fa7012e2a44cbe29af16610a747.png","alt":null,"title":null,"style":[{"key":"width","value":"75%"},{"key":"bordertype","value":"none"}],"href":null,"fromPaste":true,"pastePass":true}},{"type":"heading","attrs":{"align":null,"level":5},"content":[{"type":"text","text":"總結:","attrs":{}}]},{"type":"paragraph","attrs":{"indent":0,"number":0,"align":null,"origin":null},"content":[{"type":"text","text":"對於產品種類相對較少的情況,考慮使用簡單工廠模式。使用簡單工廠模式的客戶端只需要傳入工廠類的參數,不需要關心如何創建對象的邏輯,可以很方便地創建所需產品。","attrs":{}}]},{"type":"paragraph","attrs":{"indent":0,"number":0,"align":null,"origin":null}},{"type":"paragraph","attrs":{"indent":0,"number":0,"align":null,"origin":null},"content":[{"type":"text","text":"對於某個產品,調用者清楚地知道應該使用哪個具體工廠服務,實例化該具體工廠,生產出具體的產品來,那麼我們可以採用工廠方法模式,如JAVA中的Colletion中的iterator() 方法;","attrs":{}}]},{"type":"paragraph","attrs":{"indent":0,"number":0,"align":null,"origin":null}},{"type":"paragraph","attrs":{"indent":0,"number":0,"align":null,"origin":null},"content":[{"type":"text","text":"或者我們只是需要一種產品,而不想知道也不需要知道究竟是哪個工廠爲生產的,即最終選用哪個具體工廠的決定權在生產者一方,它們根據當前系統的情況來實例化一個具體的工廠返回給使用者,而這個決策過程這對於使用者來說是透明的,我們也可以選用工廠方法模式。","attrs":{}}]},{"type":"paragraph","attrs":{"indent":0,"number":0,"align":null,"origin":null}},{"type":"paragraph","attrs":{"indent":0,"number":0,"align":null,"origin":null},"content":[{"type":"text","text":"但是注意當需要生成的產品不多且不會增加,一個具體工廠類就可以完成任務時,可刪除抽象工廠類。這時工廠方法模式將退化到簡單工廠模式。","attrs":{}}]},{"type":"paragraph","attrs":{"indent":0,"number":0,"align":null,"origin":null}},{"type":"paragraph","attrs":{"indent":0,"number":0,"align":null,"origin":null},"content":[{"type":"text","text":"不管是簡單工廠模式還是我們的工廠方法模式考慮的都是一系列相同類型的產品,如果生產的產品類型不是一個類型,那我們怎麼處理呢,這就需要我們的工廠模式的另一種模式-抽象工廠模式。","attrs":{}}]},{"type":"paragraph","attrs":{"indent":0,"number":0,"align":null,"origin":null}},{"type":"paragraph","attrs":{"indent":0,"number":0,"align":null,"origin":null},"content":[{"type":"text","text":"​","attrs":{}}]},{"type":"paragraph","attrs":{"indent":0,"number":0,"align":null,"origin":null}},{"type":"paragraph","attrs":{"indent":0,"number":0,"align":null,"origin":null}}]}
發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章