简单工厂方法(Simple-Factory,非设计模式,创建型)
注:部分内容参考自《Head First设计模式》和GoF《设计模式:可复用面向对象软件的基础》
本文的结构:
一、简单工厂方法的定义
简单工厂方法把变化的部分(即创建对象的细节)封装起来,即通过工厂类(Factory)来处理创建对象的细节。
首先需要说明的是:简单工厂方法不是一种设计模式,它更像是一种编程习惯。个人理解,这种处理方式把创建对象的细节进行了简单的封装,单独进行管理,不再与其他操作直接关联,使之得到解耦,便于维护。工厂类的职责也比较单一和明确,不会有冗余设计。
二、示例
注:以下代码可参考《Head First设计模式》,或者【我的github】。
例如:要创建不同类型的Pizza,我们不在PizzaStore的方法中直接根据Pizza类型来创建Pizza,而是把这些创建的代码通过工厂(factory)封装起来,由factory直接负责和维护。这样PizzaStore与Pizza的创建便分离开了,后续如果有新增加的Pizza只要维护factory即可。
1、PizzaStore类
其中的pizza = factory.createPizza(type);便是由工厂类进行实际的处理。
试想下,如果把创建Pizza对象的代码直接写在PizzaStore中,后续每次新增或者删除一类Pizza,都需要对PizzaStore进行修改以适应最新的场景。实际上PizzaStore的其他流程并没有发生化,需要变化的只是Pizza的种类罢了。如果以现在的方式来维护的话,处理Pizza的工作全部由工厂类来处理,PizzaStore完全不用关心实际的创建过程,只需要按照正常的流程即可。
package com.designpatterns.creationalpatterns.simplefactory; /** * * Reference : Head-First-Design-Patterns * */ public class PizzaStore { /** * 工厂类,负责处理创建对象的具体细节 */ SimplePizzaFactory factory; public PizzaStore(SimplePizzaFactory factory) { this.factory = factory; } public void setFactory(SimplePizzaFactory factory) { this.factory = factory; } public Pizza orderPizza(String type) { Pizza pizza; /** * <p> * 这里原本是工厂方法中创建Pizza的过程,被factory进行了封装 * <p> * Here we create the pizza with factory. */ pizza = factory.createPizza(type); pizza.prepare(); pizza.bake(); pizza.cut(); pizza.box(); return pizza; } }
2、工厂类Factory
封装实际的创建对象工作。
1 package com.designpatterns.creationalpatterns.simplefactory; 2 3 4 /** 5 * <p> 6 * 简单工厂方法: 7 * <p> 8 * 把变化的部分(创建对象)封装起来,即通过工厂(factory)来处理创建对象的细节。 9 * <p> 10 * 简单工厂方法不是一种设计模式,而是一种编程习惯。 11 * 12 * Reference : Head-First-Design-Patterns 13 * 14 */ 15 16 public class SimplePizzaFactory { 17 18 /** 19 * 根据实际类型创建相应的对象 20 * @param type 21 * @return 22 */ 23 public Pizza createPizza(String type) { 24 Pizza pizza = null; 25 26 if (type.equals("cheese")) { 27 pizza = new CheesePizza(); 28 } else if (type.equals("pepperoni")) { 29 pizza = new PepperoniPizza(); 30 } else if (type.equals("clam")) { 31 pizza = new ClamPizza(); 32 } else if (type.equals("veggie")) { 33 pizza = new VeggiePizza(); 34 } 35 return pizza; 36 } 37 }
3、测试类
简单地创建了PizzaStore和工厂类,PizzaStore实际上使用工厂类进行Pizza对象的创建。
1 package com.designpatterns.creationalpatterns.simplefactory; 2 3 /** 4 * 5 * Reference : Head-First-Design-Patterns 6 * 7 */ 8 9 public class PizzaTestApp { 10 public static void main(String[] args) { 11 //创建工厂 12 SimplePizzaFactory factory = new SimplePizzaFactory(); 13 PizzaStore pizzaStore = new PizzaStore(factory); 14 15 //order a pizza 16 Pizza pizza = pizzaStore.orderPizza("clam"); 17 System.out.println("We ordered a " + pizza.getName() + " "); 18 System.out.println(pizza); 19 20 //change the pizza type 21 pizza = pizzaStore.orderPizza("veggie"); 22 System.out.println("We ordered a " + pizza.getName() + " "); 23 System.out.println(pizza); 24 25 } 26 }
简单工厂方法有以下几个变种:
- 变种1:添加多个创建的方法,负责不同对象的创建。
- 变种2:静态工厂方法,把方法设置为static,不用创建工厂实例。缺点:不能通过继承来改变创建方法的行为。
以上便是简单工厂方法的大致介绍。后面要介绍的工厂方法模式、抽象工厂模式也有相通之处。它们在工厂类的基础上进行了不同的抽象和扩展,以满足相应的场景。