【設計模式】第六篇 - 工廠方法模式

{"type":"doc","content":[{"type":"heading","attrs":{"align":null,"level":2},"content":[{"type":"text","text":"1,前言","attrs":{}}]},{"type":"codeblock","attrs":{"lang":"text"},"content":[{"type":"text","text":"如果我們說工廠方法模式是簡單工廠的升級,那麼這篇要說的抽象工廠模式就是工廠方法模式的升級\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":"link","attrs":{"href":"http://blog.csdn.net/abap_brave/article/details/78091042","title":"","type":null},"content":[{"type":"text","text":"傳送門:簡單工廠","attrs":{}}]}]},{"type":"paragraph","attrs":{"indent":0,"number":0,"align":null,"origin":null},"content":[{"type":"link","attrs":{"href":"http://blog.csdn.net/ABAP_Brave/article/details/78122014","title":"","type":null},"content":[{"type":"text","text":"傳送門:工廠方法模式","attrs":{}}]}]},{"type":"paragraph","attrs":{"indent":0,"number":0,"align":null,"origin":null}},{"type":"horizontalrule","attrs":{}},{"type":"heading","attrs":{"align":null,"level":2},"content":[{"type":"text","text":"2,需求場景和技術實現","attrs":{}}]},{"type":"paragraph","attrs":{"indent":0,"number":0,"align":null,"origin":null}},{"type":"codeblock","attrs":{"lang":"text"},"content":[{"type":"text","text":"抽象工廠Demo需求場景:\n\n 連鎖品牌餐廳X可以做4種飯:\n 沙拉烤肉飯-配方:烤肉 沙拉醬汁 米飯 蔬菜\n 沙拉雞肉飯-配方:雞肉 沙拉醬汁 米飯 蔬菜\n 番茄烤肉飯-配方:烤肉 番茄醬汁 米飯 蔬菜\n 番茄雞肉飯-配方:雞肉 番茄醬汁 米飯 蔬菜\n\n 由於供貨渠道和地域差異化,加盟店鋪A和店鋪B的製作食材有所不同:\n 加盟店鋪A:烤肉A 雞肉A 沙拉醬汁A 番茄醬汁A 長粒米飯 生菜\n 加盟店鋪B:烤肉B 雞肉B 沙拉醬汁B 番茄醬汁B 圓粒米飯 白菜\n\n 每種飯食統一的製作步驟:\n 準備食材->加工烹飪->裝盒打包\n\n分析需求:\n 店鋪A和B唯一的不同點就是製作每種\"飯\"的原料不同,其他製作流程無差異\n 所以將變化的部分抽象出來:A的原料類,和B的原料類(原料抽象工廠A和B)\n\n技術實現:\n 創建抽象\"飯\"類,具有準備,烹飪,裝盒打包方法\n 每種\"飯\"類繼承抽象\"飯\"類,重寫各個步驟的實現(根據配方不同,需要的食材原料不同)\n 每種飯的製作工藝雖然相同,但是A店鋪和B店鋪使用的原材料不同,所以四種\"飯\"飯別依賴不同的原材料類\n\n 創建一個抽象原材料接口,每個方法用於創建原材料(依賴抽象原材料)\n 實現抽象原材料接口(抽象工廠接口),創建原材料A類和原材料B類(具體工廠) 用於指定每種原材料所使用的具體原材料\n 根據原材料的類別方別製作產品抽象類(供抽象工廠依賴)和具體產品類(供具體工廠依賴)\n\n 創建店鋪抽象類,產生一個飯對象,並控制製作流程(準備食材->加工烹飪->裝盒擺放->打包外送)\n 繼承自店鋪抽象類,創建具體店鋪A和店鋪B,重寫創建具體飯的過程,並分別依賴原材料工廠A和工廠B,\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","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":"image","attrs":{"src":"https://static001.geekbang.org/infoq/b7/b707df419c90fa4d4d339a7c3874ec5e.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":"codeblock","attrs":{"lang":"text"},"content":[{"type":"text","text":"結構說明:\n com.brave.food.abstractfactory.ingredient.meat\n com.brave.food.abstractfactory.ingredient.rice\n com.brave.food.abstractfactory.ingredient.sauce\n com.brave.food.abstractfactory.ingredient.veggies\n 以上四個包中爲全部6種原材料\n\n com.brave.food.abstractfactory.factory\n RiceIngredientFactory類爲抽象原材料工廠接口,規定了每種原材料的創建\n RiceIngredientFactoryA和RiceIngredientFactoryB爲實現抽象原材料工廠接口的具體原材料工廠A和B,\n 控制每種原材料實例化的具體原材料是哪一種\n\n com.brave.food.abstractfactory.rice\n 包中Food類爲飯食超類,包含飯的屬性(名稱+6種原材料),和方法(準備,烹飪,打包)\n 其餘四個類繼承自Food類,依賴具體原材料工廠創建不同的食材,重寫準備階段的材料組合\n\n com.brave.food.abstractfactory.store\n RiceStore爲店鋪抽象類,規定了飯的同一製作流程,並將創建具體飯食延遲到子類進行\n 不同店鋪依賴不同的原材料工廠,實現相同的飯使用不同的原材料\n\n com.brave.food.abstractfactory.Client 測試類","attrs":{}}]},{"type":"paragraph","attrs":{"indent":0,"number":0,"align":null,"origin":null}},{"type":"horizontalrule","attrs":{}},{"type":"heading","attrs":{"align":null,"level":3},"content":[{"type":"text","text":"3,抽象工廠模式","attrs":{}}]},{"type":"paragraph","attrs":{"indent":0,"number":0,"align":null,"origin":null}},{"type":"codeblock","attrs":{"lang":"text"},"content":[{"type":"text","text":"抽象工廠:提供一個創建一系列相關或相互依賴對象家族的接口,而無需指定具體類\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","text":"1)原材料的簡單說明(類較多且意義不大,統一說明)","attrs":{}}]},{"type":"paragraph","attrs":{"indent":0,"number":0,"align":null,"origin":null}},{"type":"codeblock","attrs":{"lang":"java"},"content":[{"type":"text","text":" // 原材料分爲4類6種 存放於com.brave.food.abstractfactory.ingredient.*下\n protected Sauce salad; // 沙拉醬汁\n protected Sauce tomato; // 番茄醬汁\n protected Meat barbecue; // 烤肉\n protected Meat chicken; // 雞肉\n protected Rice rice; // 米飯\n protected Veggies veggies; // 蔬菜\n\n 肉類Meat\n 烤肉A BarbecueA 烤肉B BarbecueB\n 雞肉A ChickenA 雞肉B ChickenB\n 醬汁Sauce\n 沙拉醬汁A SaladSauceA 沙拉醬汁B SaladSauceB\n 番茄醬汁A TomatoSauceA 番茄醬汁B TomatoSauceB\n 米飯Rice\n 長粒米飯 LongGrainRice 圓粒米飯 RoundedGrainRice\n 蔬菜Veggies\n 白菜 Cabbage 生菜 Lettuce","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":"2)原材料抽象工廠","attrs":{}}]},{"type":"codeblock","attrs":{"lang":"java"},"content":[{"type":"text","text":"/**\n * 原料工廠接口\n * \n * 生產各種原材料\n * \n * @author Brave\n *\n */\npublic interface RiceIngredientFactory {\n\n public Meat createChicken();\n public Meat createBarbecue();\n public Sauce createTomato();\n public Sauce createSalad();\n public Rice createRice();\n public Veggies createVeggies();\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","text":"3)具體原材料工廠A","attrs":{}}]},{"type":"codeblock","attrs":{"lang":"text"},"content":[{"type":"text","text":"實現抽象原材料工廠接口的具體原材料工廠A和B,控制每種原材料實例化的具體原材料是哪一種","attrs":{}}]},{"type":"paragraph","attrs":{"indent":0,"number":0,"align":null,"origin":null}},{"type":"codeblock","attrs":{"lang":"java"},"content":[{"type":"text","text":"package com.brave.food.abstractfactory.factory;\n\nimport com.brave.food.abstractfactory.ingredient.meat.BarbecueA;\nimport com.brave.food.abstractfactory.ingredient.meat.ChickenA;\nimport com.brave.food.abstractfactory.ingredient.meat.Meat;\nimport com.brave.food.abstractfactory.ingredient.rice.LongGrainRice;\nimport com.brave.food.abstractfactory.ingredient.rice.Rice;\nimport com.brave.food.abstractfactory.ingredient.sauce.SaladSauceA;\nimport com.brave.food.abstractfactory.ingredient.sauce.Sauce;\nimport com.brave.food.abstractfactory.ingredient.sauce.TomatoSauceA;\nimport com.brave.food.abstractfactory.ingredient.veggies.Lettuce;\nimport com.brave.food.abstractfactory.ingredient.veggies.Veggies;\n\n/**\n * A原料工廠\n * \n * 烤肉A\n * 雞肉A\n * 番茄醬汁A\n * 長粒米\n * 生菜\n *\n * @author Brave\n *\n */\npublic class RiceIngredientFactoryA implements RiceIngredientFactory {\n\n @Override\n public Meat createChicken() {\n Meat chicken = new ChickenA();\n return chicken;\n }\n\n @Override\n public Meat createBarbecue() {\n Meat barbecue = new BarbecueA();\n return barbecue;\n }\n\n @Override\n public Sauce createTomato() {\n Sauce sauce = new TomatoSauceA();\n return sauce;\n }\n\n @Override\n public Sauce createSalad() {\n Sauce sauce = new SaladSauceA();\n return sauce;\n }\n\n @Override\n public Rice createRice() {\n Rice rice = new LongGrainRice();\n return rice;\n }\n\n @Override\n public Veggies createVeggies() {\n Veggies veggies = new Lettuce();\n return veggies;\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","text":"4)創建飯類統一抽象類","attrs":{}}]},{"type":"codeblock","attrs":{"lang":"java"},"content":[{"type":"text","text":"package com.brave.food.abstractfactory.rice;\n\nimport com.brave.food.abstractfactory.ingredient.meat.Meat;\nimport com.brave.food.abstractfactory.ingredient.rice.Rice;\nimport com.brave.food.abstractfactory.ingredient.sauce.Sauce;\nimport com.brave.food.abstractfactory.ingredient.veggies.Veggies;\n\n/**\n * Food統一接口\n * 各種Food實現此接口\n * 規定了Food的製作環節和屬性\n * \n * @author Brave\n *\n */\npublic abstract class Food {\n\n private String name; // 名稱\n protected Sauce salad; // 沙拉醬汁\n protected Sauce tomato; // 番茄醬汁\n protected Meat barbecue; // 烤肉\n protected Meat chicken; // 雞肉\n protected Rice rice; // 米飯\n protected Veggies veggies; // 蔬菜\n\n // 準備\n public abstract void prepare();\n\n // 烹飪\n public void cook(){\n System.out.println(\"Food-cook\");\n }\n\n // 打包\n public void pack(){\n System.out.println(\"Food-pack\");\n }\n\n public String getName() {\n return name;\n }\n\n public void setName(String name) {\n this.name = name;\n }\n\n public void print() {\n\n if(name !=null ){\n System.out.println(\"name = \" + name);\n }\n\n if(salad !=null ){\n System.out.println(\"salad = \" + salad.toString());\n }\n\n if(tomato !=null ){\n System.out.println(\"tomato = \" + tomato.toString());\n }\n\n if(chicken !=null ){\n System.out.println(\"chicken = \" + chicken.toString());\n }\n\n if(barbecue !=null ){\n System.out.println(\"barbecue = \" + barbecue.toString());\n }\n\n if(rice !=null ){\n System.out.println(\"rice = \" + rice.toString());\n }\n\n if(veggies !=null ){\n System.out.println(\"veggies = \" + veggies.toString());\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","text":"5)具體飯食(以其中一種爲例說明)","attrs":{}}]},{"type":"codeblock","attrs":{"lang":"text"},"content":[{"type":"text","text":"每種\"飯\"類繼承抽象\"飯\"類,重寫各個步驟的實現(根據配方不同,需要的食材原料不同)\n每種飯的製作工藝雖然相同,但是A店鋪和B店鋪使用的原材料不同,所以四種\"飯\"飯別依賴不同的原材料類","attrs":{}}]},{"type":"paragraph","attrs":{"indent":0,"number":0,"align":null,"origin":null}},{"type":"codeblock","attrs":{"lang":"java"},"content":[{"type":"text","text":"package com.brave.food.abstractfactory.rice;\n\nimport com.brave.food.abstractfactory.factory.RiceIngredientFactory;\n\n/**\n * 沙拉烤肉飯\n * \n * 配方:烤肉 沙拉醬汁 米飯 蔬菜\n * 工廠A:烤肉A 沙拉醬汁A 長粒米飯 生菜\n * 工廠B:烤肉B 沙拉醬汁B 圓粒米飯 白菜\n * \n * 繼承自飯食抽象類,重寫了準備過程prepare()\n * \n * @author Brave\n *\n */\npublic class SaladBarbecueRice extends Food {\n\n RiceIngredientFactory ingredientFactory;\n\n public SaladBarbecueRice(RiceIngredientFactory ingredientFactory) {\n this.ingredientFactory = ingredientFactory;\n }\n\n @Override\n public void prepare() {\n\n System.out.println(\"Preparing \" + getName());\n\n barbecue = ingredientFactory.createBarbecue();\n salad = ingredientFactory.createSalad();\n rice = ingredientFactory.createRice();\n veggies = ingredientFactory.createVeggies();\n\n this.print();\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","text":"6)創建店鋪抽象類(工廠方法模式)","attrs":{}}]},{"type":"codeblock","attrs":{"lang":"text"},"content":[{"type":"text","text":"RiceStore爲店鋪抽象類,規定了飯的同一製作流程,並將創建具體飯食延遲到子類進行","attrs":{}}]},{"type":"paragraph","attrs":{"indent":0,"number":0,"align":null,"origin":null}},{"type":"codeblock","attrs":{"lang":"java"},"content":[{"type":"text","text":"package com.brave.food.abstractfactory.store;\n\nimport com.brave.food.abstractfactory.rice.Food;\n\n/**\n * 飯店抽象類\n * \n * 控制了統一的製作流程\n * 將創建具體對象的操作延遲到子類\n * \n * @author Brave\n *\n */\npublic abstract class RiceStore {\n\n public Food orderRice(String type){\n\n Food rice;\n\n rice = this.createRice(type);\n\n System.out.println(\"-----------\"+type+\"----------\");\n\n rice.prepare();\n rice.cook();\n rice.pack();\n\n return rice;\n }\n\n protected abstract Food createRice(String type);\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","text":"7)創建具體店鋪","attrs":{}}]},{"type":"codeblock","attrs":{"lang":"text"},"content":[{"type":"text","text":"RiceStoreA和RiceStoreB爲繼承自RiceStore的具體店鋪\n重寫了各種飯的製作方法,不同店鋪依賴不同的原材料工廠,實現相同的飯使用不同的原材料","attrs":{}}]},{"type":"paragraph","attrs":{"indent":0,"number":0,"align":null,"origin":null}},{"type":"codeblock","attrs":{"lang":"java"},"content":[{"type":"text","text":"package com.brave.food.abstractfactory.store;\n\nimport java.lang.reflect.Constructor;\nimport java.lang.reflect.InvocationTargetException;\n\nimport com.brave.food.abstractfactory.factory.RiceIngredientFactory;\nimport com.brave.food.abstractfactory.factory.RiceIngredientFactoryA;\nimport com.brave.food.abstractfactory.rice.Food;\nimport com.brave.food.abstractfactory.rice.SaladBarbecueRice;\nimport com.brave.food.abstractfactory.rice.SaladChickenRice;\nimport com.brave.food.abstractfactory.rice.TomatoBarbecueRice;\nimport com.brave.food.abstractfactory.rice.TomatoChickenRice;\n\n/**\n * 飯店A\n * \n * 使用A原料工廠提供製作材料\n * \n * @author Brave\n *\n */\npublic class RiceStoreA extends RiceStore {\n\n @Override\n protected Food createRice(String type) {\n\n Food rice = null;\n RiceIngredientFactory ingredientFactory = new RiceIngredientFactoryA();\n\n if(type.equals(\"TomatoBarbecue\")){\n rice = new TomatoBarbecueRice(ingredientFactory);\n rice.setName(\"TomatoBarbecueRice\");\n } else if(type.equals(\"TomatoChicken\")){\n rice = new TomatoChickenRice(ingredientFactory);\n rice.setName(\"TomatoChickenRice\");\n } else if(type.equals(\"SaladChicken\")){\n rice = new SaladChickenRice(ingredientFactory);\n rice.setName(\"SaladChickenRice\");\n } else if(type.equals(\"SaladBarbecue\")){\n rice = new SaladBarbecueRice(ingredientFactory);\n rice.setName(\"SaladBarbecueRice\");\n }\n\n// try {\n// Constructor c = null;\n// Class clazz = null;\n// try {\n// clazz = Class.forName(TomatoBarbecueRice.class.getName());\n// } catch (ClassNotFoundException e) {\n// System.out.println(\"類不存在\");\n// e.printStackTrace();\n// }\n// c = clazz.getConstructor(RiceIngredientFactory.class);\n// try {\n// Food rice1 = (Food) c.newInstance(ingredientFactory);\n// rice1.setName(\"SaladBarbecueRice\");\n// } catch (InstantiationException e) {\n// System.out.println(\"不支持抽象類或接口\");\n// e.printStackTrace();\n// } catch (IllegalAccessException e) {\n// System.out.println(\"沒有足夠權限,即不能訪問私有對象\");\n// e.printStackTrace();\n// } catch (IllegalArgumentException e) {\n// e.printStackTrace();\n// } catch (InvocationTargetException e) {\n// e.printStackTrace();\n// } \n// } catch (NoSuchMethodException e) {\n// e.printStackTrace();\n// } catch (SecurityException e) {\n// e.printStackTrace();\n// } finally {\n// \n// }\n\n return rice;\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","text":"8)測試類","attrs":{}}]},{"type":"codeblock","attrs":{"lang":"java"},"content":[{"type":"text","text":"package com.brave.food.abstractfactory;\n\nimport com.brave.food.abstractfactory.store.RiceStore;\nimport com.brave.food.abstractfactory.store.RiceStoreA;\nimport com.brave.food.abstractfactory.store.RiceStoreB;\n\npublic class Client {\n\n public static void main(String[] args) {\n\n // 店鋪A和店鋪B\n RiceStore riceStoreA = new RiceStoreA();\n RiceStore riceStoreB = new RiceStoreB();\n\n // 番茄烤肉飯\n// riceStoreA.orderRice(\"TomatoBarbecue\");\n// riceStoreB.orderRice(\"TomatoBarbecue\");\n\n // 番茄雞肉飯\n// riceStoreA.orderRice(\"TomatoChicken\");\n// riceStoreB.orderRice(\"TomatoChicken\");\n\n // 沙拉烤肉飯\n// riceStoreA.orderRice(\"SaladChicken\");\n// riceStoreB.orderRice(\"SaladChicken\");\n\n // 沙拉雞肉飯\n riceStoreA.orderRice(\"SaladBarbecue\");\n riceStoreB.orderRice(\"SaladBarbecue\");\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","text":"打印輸出:","attrs":{}}]},{"type":"codeblock","attrs":{"lang":"text"},"content":[{"type":"text","text":"-----------SaladBarbecue----------\nPreparing SaladBarbecueRice\nname = SaladBarbecueRice\nsalad = 沙拉醬汁A\nbarbecue = 烤肉A\nrice = 長粒米飯\nveggies = 生菜\nFood-cook\nFood-pack\n-----------SaladBarbecue----------\nPreparing SaladBarbecueRice\nname = SaladBarbecueRice\nsalad = 沙拉醬汁B\nbarbecue = 烤肉B\nrice = 圓粒米飯\nveggies = 白菜\nFood-cook\nFood-pack","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":"從Log輸出可以看到,店鋪A和B 製作相同的飯,製作流程相同,使用的原材料不同","attrs":{}}]},{"type":"paragraph","attrs":{"indent":0,"number":0,"align":null,"origin":null}},{"type":"horizontalrule","attrs":{}},{"type":"heading","attrs":{"align":null,"level":3},"content":[{"type":"text","text":"4,抽象工廠模式總結+優缺點","attrs":{}}]},{"type":"paragraph","attrs":{"indent":0,"number":0,"align":null,"origin":null}},{"type":"codeblock","attrs":{"lang":"text"},"content":[{"type":"text","text":"原料工廠接口(抽象工廠接口:爲產品家族提供接口)\n\n生產各種原材料\n 抽象工廠:提供一個創建一系列相關或相互依賴對象家族的接口,而無需指定具體類\n 抽象工廠模式爲產品系提供瞭解決方案\n 抽象工廠適用場景:\n 1,一個系列要獨立於他的產品的創建,組合和表示時\n 2,一個系統要由多個產品系列中的一個來配置時\n 3,當要強調一系列相關的產品對象的設計以便進行聯合使用時\n 4,當要提供一個產品類庫,而只要顯示他們的接口而不是實現時\n\n 優點:\n 客戶端經常需要切換配置(交換產品系列)時,客戶端通過抽象接口來操縱實例,具體類名不會出現在客戶端\n 抽象工廠允許客戶使用抽象接口來創建一組相關的產品,而不需要關心實際產出的具體產品是什麼,使客戶從具體產品中解耦\n\n 缺點:\n 抽象工廠模式便於交換產品系列的同時,再改動聲明過產品類的地方進行大量修改\n解決方法:\n添加if,Switch分支判斷或者反射(反射的實現方式已包含在代碼中的註釋部分)\n\n通過抽象工廠提供的接口創建產品家族,使代碼從實際工廠解耦,在不同的上下文實現各種工廠,製造不同產品\n由於代碼從實際產品中解耦,我們可以替換不同工廠來取得不同的行爲","attrs":{}}]},{"type":"paragraph","attrs":{"indent":0,"number":0,"align":null,"origin":null}},{"type":"horizontalrule","attrs":{}},{"type":"heading","attrs":{"align":null,"level":3},"content":[{"type":"text","text":"5,三種工廠模式","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":"1)三種模式的比較","attrs":{}}]},{"type":"codeblock","attrs":{"lang":"text"},"content":[{"type":"text","text":"簡單工廠:\n雖然不是真正的設計模式,但卻是一個簡單的方法\n去除了客戶端和具體產品的依賴,增強了代碼移植性\n\n工廠方法模式:\n使用繼承實現,將對象的創建委託給子類(將對象的實例化延遲到子類),子類實現工廠方法來創建對象\n客戶端只需要知道所使用的抽象類型,不用關心具體類型\n工廠方法模式,只負責將客戶端從具體類型中解耦\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","text":"2)三種模式的優缺點","attrs":{}}]},{"type":"codeblock","attrs":{"lang":"text"},"content":[{"type":"text","text":"簡單工廠-優點:\n去除了客戶端和具體產品的依賴,增強了代碼移植性\n簡單工廠-缺點:\n違背了開放-封閉原則\n添加新產品比較麻煩\n\n工廠方法模式-優點:\n使用繼承實現,將對象的創建委託給子類(將對象的實例化延遲到子類),子類實現工廠方法來創建對象\n客戶端只需要知道所使用的抽象類型,不用關心具體類型\n工廠方法模式,只負責將客戶端從具體類型中解耦\n後臺模塊契合了開放-封閉原則\n工廠方法模式-缺點:\n添加新產品需要創建大量新的類\n客戶端部分仍然違反開放-封閉原則,只是後臺判斷邏輯轉移到了前臺\n\n抽象工廠模式-優點:\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","text":"3)工廠模式共同點:","attrs":{}}]},{"type":"codeblock","attrs":{"lang":"text"},"content":[{"type":"text","text":"1,封裝對象創建過程\n2,減少客戶端和具體類之間的依賴,促進松耦合\n3,符合依賴倒置原則,不能讓高層組件依賴低層組件,依賴抽象不依賴具體","attrs":{}}]},{"type":"paragraph","attrs":{"indent":0,"number":0,"align":null,"origin":null}}]}
發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章