设计模式笔记4:简单工厂模式(Simple Factory Pattern)

来源:互联网 发布:135端口入侵教程 编辑:程序博客网 时间:2024/06/11 05:56

一、简单工厂模式的内容

简单工厂模式(Simple Factory Pattern):又称为静态工厂方法(Static Factory Method)模式,它属于类创建型模式。在简单工厂模式中,可以根据参数的不同返回不同类的实例。简单工厂模式专门定义一个类来负责创建其他类的实例,被创建的实例通常都具有共同的父类。
Simple Factory模式实际上不是GoF 23个设计模式中的一员。其封转了变化,但是封装的方式有待商榷。

二、简单工厂模式的结构


涉及到的角色:
工厂类角色Creator (LightSimpleFactory):工厂类在客户端的直接控制下(Create方法)创建产品对象。
抽象产品角色Product (Light):定义简单工厂创建的对象的父类或它们共同拥有的接口。可以是一个类、抽象类或接口。
具体产品角色ConcreteProduct (BulbLight, TubeLight):定义工厂具体加工出的对象。

三、模式分析

  • 将对象的创建和对象本身业务处理分离可以降低系统的耦合度,使得两者修改起来都相对容易。 
  • 在调用工厂类的工厂方法时,由于工厂方法是静态方法,使用起来很方便,可通过类名直接调用,而且只需要传入一个简单的参数即可,在实际开发中,还可以在调用时将所传入的参数保存在XML等格式的配置文件中,修改参数时无须修改任何Java源代码。
  • 简单工厂模式最大的问题在于工厂类的职责相对过重,增加新的产品需要修改工厂类的判断逻辑,这一点与开闭原则是相违背的。
  • 简单工厂模式的要点在于:当你需要什么,只需要传入一个正确的参数,就可以获取你所需要的对象,而无须知道其创建细节。

四、简单工厂模式代码示例

import java.util.ArrayList;abstract public class Pizza {String name;String dough;String sauce;ArrayList toppings = new ArrayList();public String getName() {return name;}public void prepare() {System.out.println("Preparing " + name);}public void bake() {System.out.println("Baking " + name);}public void cut() {System.out.println("Cutting " + name);}public void box() {System.out.println("Boxing " + name);}public String toString() {// code to display pizza name and ingredientsStringBuffer display = new StringBuffer();display.append("---- " + name + " ----\n");display.append(dough + "\n");display.append(sauce + "\n");for (int i = 0; i < toppings.size(); i++) {display.append((String )toppings.get(i) + "\n");}return display.toString();}}

public class PepperoniPizza extends Pizza {public PepperoniPizza() {name = "Pepperoni Pizza";dough = "Crust";sauce = "Marinara sauce";toppings.add("Sliced Pepperoni");toppings.add("Sliced Onion");toppings.add("Grated parmesan cheese");}}

public class ClamPizza extends Pizza {public ClamPizza() {name = "Clam Pizza";dough = "Thin crust";sauce = "White garlic sauce";toppings.add("Clams");toppings.add("Grated parmesan cheese");}}

public class CheesePizza extends Pizza {public CheesePizza() {name = "Cheese Pizza";dough = "Regular Crust";sauce = "Marinara Pizza Sauce";toppings.add("Fresh Mozzarella");toppings.add("Parmesan");}}

public class VeggiePizza extends Pizza {public VeggiePizza() {name = "Veggie Pizza";dough = "Crust";sauce = "Marinara sauce";toppings.add("Shredded mozzarella");toppings.add("Grated parmesan");toppings.add("Diced onion");toppings.add("Sliced mushrooms");toppings.add("Sliced red pepper");toppings.add("Sliced black olives");}}

public class SimplePizzaFactory {public Pizza createPizza(String type) {//此处的方法改为static即为static factory methodPizza pizza = null;if (type.equals("cheese")) {pizza = new CheesePizza();} else if (type.equals("pepperoni")) {pizza = new PepperoniPizza();} else if (type.equals("clam")) {pizza = new ClamPizza();} else if (type.equals("veggie")) {pizza = new VeggiePizza();}return pizza;}}
public class PizzaStore {SimplePizzaFactory factory; public PizzaStore(SimplePizzaFactory factory) { this.factory = factory;} public Pizza orderPizza(String type) {Pizza pizza; pizza = factory.createPizza(type); pizza.prepare();pizza.bake();pizza.cut();pizza.box();return pizza;}}

public class PizzaTestDrive { public static void main(String[] args) {SimplePizzaFactory factory = new SimplePizzaFactory();PizzaStore store = new PizzaStore(factory);Pizza pizza = store.orderPizza("cheese");System.out.println("We ordered a " + pizza.getName() + "\n"); pizza = store.orderPizza("veggie");System.out.println("We ordered a " + pizza.getName() + "\n");}}


五、 优点与缺点:

优点:

  • 工厂类含有必要的判断逻辑,可以决定在什么时候创建哪一个产品类的实例,客户端可以免除直接创建产品对象的责任,而仅仅“消费”产品;简单工厂模式通过这种做法实现了对责任的分割,它提供了专门的工厂类用于创建对象。
  • 客户端无须知道所创建的具体产品类的类名,只需要知道具体产品类所对应的参数即可,对于一些复杂的类名,通过简单工厂模式可以减少使用者的记忆量。
  • 通过引入配置文件,可以在不修改任何客户端代码的情况下更换和增加新的具体产品类,在一定程度上提高了系统的灵活性。

缺点:

  • 当产品有复杂的多层等级结构时,工厂类只有自己,以不变应万变,就是模式的缺点。由于工厂类集中了所有产品创建逻辑,一旦不能正常工作,整个系统都要受到影响。
  • 使用简单工厂模式将会增加系统中类的个数,在一定程序上增加了系统的复杂度和理解难度。
  • 系统扩展困难,一旦添加新产品就不得不修改工厂逻辑,在产品类型较多时,有可能造成工厂逻辑过于复杂,不利于系统的扩展和维护。
  • 简单工厂模式由于使用了静态工厂方法,造成工厂角色无法形成基于继承的等级结构。(待商榷)

六、模式适用环境

在以下情况下可以使用简单工厂模式:
  • 工厂类负责创建的对象比较少:由于创建的对象较少,不会造成工厂方法中的业务逻辑太过复杂。
  • 客户端只知道传入工厂类的参数,对于如何创建对象不关心:客户端既不需要关心创建细节,甚至连类名都不需要记住,只需要知道类型所对应的参数。

七、在JDK当中的应用

  • java.text.DateFormat,它用于格式化一个本地日期或者时间。
public final static DateFormat getDateInstance();
public final static DateFormat getDateInstance(int style);
public final static DateFormat getDateInstance(int style,Locale locale);
  • Java加密技术
//获取不同加密算法的密钥生成器
KeyGenerator keyGen=KeyGenerator.getInstance("DESede");
//创建密码器
Cipher cp=Cipher.getInstance("DESede");

八、参考文献

  1. http://blog.csdn.net/rocket5725/article/details/4295382
  2. 《Head First 设计模式》
  3. 《设计模式》刘伟主编清华大学出版社

原创粉丝点击