无论是工厂方法还是抽象工厂,所谓工厂就是生产之用,工厂方法的作用就是生产一个对象。

工厂方法的定义为:为创建对象定义一个接口,但是让子类决定实例化哪一个类。工厂方法让一个类把实例化推迟到子类。

英文定义为: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. 可以看出,工厂方法将抽象与实现分离开来,可以让客户端不用关心对象的具体实现,只需关心对象见的关系。

抽象工厂的结构图如下

【设计模式】之工厂方法(Factory Method)_string

如果父类中的工厂方法没有实现内容,就用到了模板方法(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;
}
}




factory method 与 abstract factory的区别是 factory method只生产一个产品,而abstract factory则生产的是families of products.

abstract factory为生产产品集中的每一个产品时可以使用factory method。