【设计模式】第六篇 - 工厂方法模式

{"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}}]}
發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章