设计模式抽象工厂模式.doc_第1页
设计模式抽象工厂模式.doc_第2页
设计模式抽象工厂模式.doc_第3页
设计模式抽象工厂模式.doc_第4页
设计模式抽象工厂模式.doc_第5页
已阅读5页,还剩4页未读 继续免费阅读

下载本文档

版权说明:本文档由用户提供并上传,收益归属内容提供方,若内容存在侵权,请进行举报或认领

文档简介

设计模式读书笔记-抽象工厂模式 在工厂方法模式中,我们使用一个工厂创建一个产品,也就是说一个具体的工厂对应一个具体的产品。但是有时候我们需要一个工厂能够提供多个产品对象,而不是单一的对象,这个时候我们就需要使用抽象工厂模式。 在讲解抽象工厂模式之前,我们需要厘清两个概念: 产品等级结构。产品的等级结构也就是产品的继承结构。例如一个为空调的抽象类,它有海尔空调、格力空调、美的空调等一系列的子类,那么这个抽象类空调和他的子类就构成了一个产品等级结构。 产品族。产品族是在抽象工厂模式中的。在抽象工厂模式中,产品族是指由同一个工厂生产的,位于不同产品等级结构中的一组产品。比如,海尔工厂生产海尔空调。海尔冰箱,那么海尔空调则位于空调产品族中。 产品等级结构和产品族结构示意图如下: 一、基本定义 抽象工厂模式提供一个接口,用于创建相关或者依赖对象的家族,而不需要明确指定具体类。 抽象工厂允许客户端使用抽象的接口来创建一组相关的产品,而不需要关系实际产出的具体产品是什么。这样一来,客户就可以从具体的产品中被解耦。 二、模式结构 抽象工厂模式的UML结构图如下: 模式结构说明。 AbstractFactory:抽象工厂。抽象工厂定义了一个接口,所有的具体工厂都必须实现此接口,这个接口包含了一组方法用来生产产品。 ConcreteFactory:具体工厂。具体工厂是用于生产不同产品族。要创建一个产品,客户只需要使用其中一个工厂完全不需要实例化任何产品对象。 AbstractProduct:抽象产品。这是一个产品家族,每一个具体工厂都能够生产一整组产品。 Product:具体产品。 三、模式实现 依然是披萨店。为了要保证每家加盟店都能够生产高质量的披萨,防止使用劣质的原料,我们打算建造一家生产原料的工厂,并将原料运送到各家加盟店。但是加盟店都位于不同的区域,比如纽约、芝加哥。纽约使用一组原料,芝加哥使用另一种原料。在这里我们可以这样理解,这些不同的区域组成了原料家族,每个区域实现了一个完整的原料家族。 首先创建一个原料工厂。该工厂为抽象工厂,负责创建所有的原料。 PizzaIngredientFactory.java1 public interface PizzaIngredientFactory 2 /* 3 * 在接口中,每个原料都有一个对应的方法创建该原料 4 */ 5 public Dough createDough(); 6 7 public Sauce createSauce(); 8 9 public Cheese createCheese();10 11 public Veggies createVeggies();12 13 public Pepperoni createPepperoni();14 15 public Clams createClams();16 原料工厂创建完成之后,需要创建具体的原料工厂。该具体工厂只需要继承PizzaIngredientFactory,然后实现里面的方法即可。 纽约原料工厂:NYPizzaIngredientFactory.java。1 public class NYPizzaIngredientFactory implements PizzaIngredientFactory 2 3 Override 4 public Cheese createCheese() 5 return new ReggianoCheese(); 6 7 8 Override 9 public Clams createClams() 10 return new FreshClams();11 12 13 Override14 public Dough createDough() 15 return new ThinCrustDough();16 17 18 Override19 public Pepperoni createPepperoni() 20 return new SlicedPepperoni();21 22 23 Override24 public Sauce createSauce() 25 return new MarinaraSauce();26 27 28 Override29 public Veggies createVeggies() 30 Veggies veggies = new Garlic(),new Onion(),new Mushroom(),new RefPepper();31 return veggies;32 33 34 重新返回到披萨。在这个披萨类里面,我们需要使用原料,其他方法保持不变,将prepare()方法声明为抽象,在这个方法中,我们需要收集披萨所需要的原料。 Pizza.java 1 public abstract class Pizza 2 /* 3 * 每个披萨都持有一组在准备时会用到的原料 4 */ 5 String name; 6 Dough dough; 7 Sauce sauce; 8 Veggies veggies; 9 Cheese cheese;10 Pepperoni pepperoni;11 Clams clams;12 13 /*14 * prepare()方法声明为抽象方法。在这个方法中,我们需要收集披萨所需要的原料,而这些原料都是来自原料工厂15 */16 abstract void prepare();17 18 void bake()19 System.out.println(Bake for 25 munites at 350);20 21 22 void cut()23 System.out.println(Cutting the pizza into diagonal slices);24 25 26 void box()27 System.out.println(Place pizza in official PizzaStore box);28 29 30 public String getName() 31 return name;32 33 34 public void setName(String name) 35 = name;36 37 38 CheesePizza.java1 public class CheesePizza extends Pizza 2 PizzaIngredientFactory ingredientFactory; 3 4 /* 5 * 要制作披萨必须要有制作披萨的原料,而这些原料是从原料工厂运来的 6 */ 7 public CheesePizza(PizzaIngredientFactory ingredientFactory) 8 this.ingredientFactory = ingredientFactory; 9 prepare();10 11 12 /*13 * 实现prepare方法14 * prepare 方法一步一步地创建芝士比萨,每当需要原料时,就跟工厂要15 */16 void prepare() 17 System.out.println(Prepareing + name);18 dough = ingredientFactory.createDough();19 sauce = ingredientFactory.createSauce();20 cheese = ingredientFactory.createCheese();21 22 23 Pizza的代码利用相关的工厂生产原料。所生产的原料依赖所使用的工厂,Pizza类根本不关心这些原料,它只需要知道如何制作披萨即可。这里,Pizza和区域原料之间被解耦。 ClamPizza.java1 public class ClamPizza extends Pizza 2 3 PizzaIngredientFactory ingredientFactory; 4 5 public ClamPizza(PizzaIngredientFactory ingredientFactory) 6 this.ingredientFactory = ingredientFactory; 7 8 9 Override10 void prepare() 11 System.out.println(Prepare + name);12 dough = ingredientFactory.createDough();13 sauce = ingredientFactory.createSauce();14 cheese = ingredientFactory.createCheese();15 clams = ingredientFactory.createClams(); 16 17 18 做完披萨后,需要关注披萨店了。 在披萨店中,我们依然需要关注原料,当地的披萨店需要和本地的原料工厂关联起来。 PizzaStore.java 1 public abstract class PizzaStore 2 public Pizza orderPizza(String type) 3 Pizza pizza; 4 pizza = createPizza(type); 5 6 pizza.prepare(); 7 pizza.bake(); 8 pizza.cut(); 9 pizza.box();10 11 return pizza;12 13 14 /*15 * 创建pizza的方法交给子类去实现16 */17 abstract Pizza createPizza(String type);18 纽约的披萨店:NYPizzaStore.java1 public class NYPizzaStore extends PizzaStore 2 3 Override 4 Pizza createPizza(String type) 5 Pizza pizza = null; 6 /使用纽约的原料工厂 7 PizzaIngredientFactory ingredientFactory = new NYPizzaIngredientFactory(); 8 if(cheese.equals(type) 9 pizza = new CheesePizza(ingredientFactory);10 pizza.setName(New York Style Cheese Pizza);11 12 else if(veggie.equals(type)13 pizza = new VeggiePizza(ingredientFactory);14 pizza.setName(New York Style Veggie Pizza);15 16 else if(clam.equals(type)17 pizza = new ClamPizza(ingredientFactory);18 pizza.setName(New York Style Clam Pizza);19 20 else if(pepperoni.equals(type)21 pizza = new PepperoniPizza(ingredientFactory);22 pizza.setName(New York Style Pepperoni Pizza);23 24 return pizza;25 26 下图是上面的UML结构图。 其中PizzaIngredientFactory是抽象的披萨原料工厂接口,它定义了如何生产一个相关产品的家族。这个家族包含了所有制作披萨的原料。 NYPizzaIngredientFactory和ChicagoPizzaIngredientFactory是两个具体披萨工厂类,他们负责生产相应的披萨原料。 NYPizzaStore是抽象工厂的客户端。 四、模式优缺点 优点 1、 抽象工厂隔离了具体类的生成,是的客户端不需要知道什么被创建。所有的具体工厂都实现了抽象工厂中定义的公共接口,因此只需要改变具体工厂的实例,就可以在某种程度上改变整个软件系统的行为。 2、 当一个产品族中的多个对象被设计成一起工作时,它能够保证客户端始终只使用同一个产品族中的对象。 缺点 添加新的行为时比较麻烦。如果需要添加一个新产品族对象时,需要更改接口及其下所有子类,这必然会带来很大的麻烦。 五、模式使用场景 1. 一个系统不应当依

温馨提示

  • 1. 本站所有资源如无特殊说明,都需要本地电脑安装OFFICE2007和PDF阅读器。图纸软件为CAD,CAXA,PROE,UG,SolidWorks等.压缩文件请下载最新的WinRAR软件解压。
  • 2. 本站的文档不包含任何第三方提供的附件图纸等,如果需要附件,请联系上传者。文件的所有权益归上传用户所有。
  • 3. 本站RAR压缩包中若带图纸,网页内容里面会有图纸预览,若没有图纸预览就没有图纸。
  • 4. 未经权益所有人同意不得将文件中的内容挪作商业或盈利用途。
  • 5. 人人文库网仅提供信息存储空间,仅对用户上传内容的表现方式做保护处理,对用户上传分享的文档内容本身不做任何修改或编辑,并不能对任何下载内容负责。
  • 6. 下载文件中如有侵权或不适当内容,请与我们联系,我们立即纠正。
  • 7. 本站不保证下载资源的准确性、安全性和完整性, 同时也不承担用户因使用这些下载资源对自己和他人造成任何形式的伤害或损失。

评论

0/150

提交评论