GoF 经典定义:Define an interface for creating an object, but let subclasses decide which class to initiate. Factory Method lets a class defer instantiation to subclasses.(定义一个用于创建对象的接口,让子类决定实例化哪一个类。工厂方法使一个类的实例化延迟到子类。)

通用UML图

Factory UML

简单工厂模式

产品类

 1
 2
 3
 4
 5
 6
 7
 8
 9
10
11
12
13
14
15
public abstract class Product {
	void method();
}

public class ConcreteProduct1 extends Product {
	public void method() {
		System.out.println("invoke ConcreteProduct1 method!");
	}
}

public class ConcreteProduct2 extends Product {
	public void method() {
		System.out.println("invoke ConcreteProduct2 method!");
	}
}

产品工厂

 1
 2
 3
 4
 5
 6
 7
 8
 9
10
11
12
13
14
15
public interface Factory {
	Product createProduct();
}

public class Product1Factory implements Factory {
	public Product createProduct() {
		return new ConcreteProduct1();
	}
}

public class Product2Factory implements Factory {
	public Product createProduct() {
		return new ConcreteProduct2();
	}
}

客户

1
2
3
4
5
6
7
8
9
public class Client {
	public static void main(String[] args) {
		Product p1 = new Product1Factory().createProduct();
		Product p2 = new Product2Factory().createProduct();

		p1.method();
		p2.method();
	}
}

输出

1
2
invoke ConcreteProduct1 method!
invoke ConcreteProduct2 method!

参数化工厂

 1
 2
 3
 4
 5
 6
 7
 8
 9
10
public class ParamFactory {
	public Product createProduct(String cName) throws NotImplementProduct {
		if (cName.compareTo("ConcreteProduct1") == 0)
			return new ConcreteProduct1();
		else if (cName.compareTo("ConcreteProduct2") == 0)
			return new ConcreteProduct2();
		else
			throw new NotImplementProduct(cName);
	}
}

上述方法需要添加新具体类时需要修改工厂代码,如果充分实现OO,可以使用泛型,代码如下。

 1
 2
 3
 4
 5
 6
 7
 8
 9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
public interface Creator {
	<T extends Product> T createProduct(Class<T> c);
}

public class ProductCreator implements Creator {
	public <T extends Product> T createProduct(Class<T> c) {
		Product product = null;
		try {
			product = (Product) Class.forName(c.getName()).newInstance();
		} catch (Exception e) {

		}

		return (T)product;
	}
}

public class Client {
	public static void main(String[] args) {
		Creator creator = new ProductCreator();
		Product p1 = creator.createProduct(ConcreteProduct1.class);
		Product p2 = creator.createProduct(ConcreteProduct2.class);


		p1.method();
		p2.method();
	}
}

可以更简单一点,取消工厂接口(基类),将工厂方法定义为静态方法,这种模式适合小模块使用。如果具体产品类构造函数复杂,还是采用第一种模式为佳。

延迟初始化

延迟初始化(Lazy Initialization)是工厂模式的一个扩展应用,一个对象被消费完毕后,并不立刻释放,工厂类保持其初始状态,等待再次被使用。

 1
 2
 3
 4
 5
 6
 7
 8
 9
10
11
12
13
14
15
16
17
18
19
20
21
22
public class LazyFactory {
	private static final Map<String, Product> pMap = new HashMap<>();
	public static synchronized Product
	createProduct(String type) throws Exception {
		Product product = null;

		if (pMap.containsKey(type)) {
			product = pMap.get(type);
		} else {
			if (type.equals("ConcreteProduct1")) {
				product = new ConcreteProduct1();
			} else if (type.equals("ConcreteProduct2")) {
				product = new ConcreteProduct2();
			} else {
				throw new NotImplementProduct(type);
			}
			pMap.put(type, product);
		}

		return product;
	}
}

抽象工厂方法

上述的简单扩展