【设计模式】之工厂方法(Factory Method)
无论是工厂方法还是抽象工厂,所谓工厂就是生产之用,工厂方法的作用就是生产一个对象。
工厂方法的定义为:为创建对象定义一个接口,但是让子类决定实例化哪一个类。工厂方法让一个类把实例化推迟到子类。
英文定义为:Define an interface for creating an object, but let subclasses decide which class to instantiate. Factory Method lets a class defter instantiation to subclasses.
《Header First》介绍一个OO设计的原则----Depend Upon abstractions. Do not depend upon concrete classes. 可以在<GOF>中找到类似说法Frameworks use abstract classes to define and maintain relationships between objects. 可以看出,工厂方法将抽象与实现分离开来,可以让客户端不用关心对象的具体实现,只需关心对象见的关系。
抽象工厂的结构图如下

如果父类中的工厂方法没有实现内容,就用到了模板方法(template method)的设计模式,如果有实现内容,则工厂方法提供了生成一个默认对象的方法,这样增加了工厂方法的灵活性,子类可以无需override。
在平行继承的结构中,工厂方法可以起到联系两个继承体系的作用;
可以在工厂方法中使用lazy initialization.
工厂方法使用应该是非常广泛,下面给出的示例代码来自<Header First>
public abstract class PizzaStore { public Pizza orderPizza(String type) { Pizza pizza; pizza = createPizza(type); pizza.prepare(); pizza.bake(); pizza.cut(); pizza.box(); return pizza; } protected abstract Pizza createPizza(String type);}public class NYPizzaStore extends PizzaStore { public Pizza createPizza(String type) { if (type.equals("cheese")) { return new NYStyleCheesePizza(); } return null; }}public class ChicagoPizzaStore extends PizzaStore { protected Pizza createPizza(String type) { if (type.equals("cheese")) { return new ChicagoStyleCheesePizza(); } return null; }}import java.util.ArrayList;public abstract class Pizza { String name; String dough; String sauce; ArrayList<String> toppings = new ArrayList<String>(); void prepare() { System.out.println("Preparing " + name); System.out.println("Tossing dough..."); System.out.println("Adding sauce..."); System.out.println("Adding toppings: "); for (int i = 0; i < toppings.size(); i++) { System.out.println(" " + toppings.get(i)); } } void bake() { System.out.println("Bake for 25 minutes at 350"); } void cut() { System.out.println("Cutting the pizza into diagonal slices"); } void box() { System.out.println("Place pizza in official PizzaStore box"); } public String getName() { return name; }}public class NYStyleCheesePizza extends Pizza { public NYStyleCheesePizza() { name = "NY Style Sause and Cheese Pizza"; dough = "Thin Crust Dough"; sauce = "Marinara Sauce"; toppings.add("Grated Reggiano Cheese"); }}public class ChicagoStyleCheesePizza extends Pizza { public ChicagoStyleCheesePizza() { name = "Chicago Style Deep Dish Cheese Pizza"; dough = "Extra Thick Crust Dough"; sauce = "Plum Tomato Sauce"; toppings.add("Shredded Mozzarella Cheese"); } void cut() { System.out.println("Cutting the pizza into square slices"); }}import java.util.ArrayList;public abstract class Pizza { String name; String dough; String sauce; ArrayList<String> toppings = new ArrayList<String>(); void prepare() { System.out.println("Preparing " + name); System.out.println("Tossing dough..."); System.out.println("Adding sauce..."); System.out.println("Adding toppings: "); for (int i = 0; i < toppings.size(); i++) { System.out.println(" " + toppings.get(i)); } } void bake() { System.out.println("Bake for 25 minutes at 350"); } void cut() { System.out.println("Cutting the pizza into diagonal slices"); } void box() { System.out.println("Place pizza in official PizzaStore box"); } public String getName() { return name; }}abstract factory为生产产品集中的每一个产品时可以使用factory method。