定义
定义一个用于创建对象的接口(IFactory),让子类(ConcreteFactory)决定实例化哪个类。
使用场景
在任何需要生成复杂对象的地方,都可以使用工厂方法模式。
需要注意的是,用new操作符就可以完成对象的创建就无需使用工厂模式。
类图
代码实现
/**
* 抽象产品类
* 定义一系列产品应该实现的服务,即产品的共性
*/
abstract class Product {
public abstract void method01();
public abstract void method02();
}
/**
* 具体产品实现类A
*/
class ConcreteProductA extends Product {
public void method01() {
System.out.println("ConcreteProductA method01() ...");
}
public void method02() {
System.out.println("ConcreteProductA method02() ...");
}
}
/**
* 具体产品实现类B
*/
class ConcreteProductB extends Product {
public void method01() {
System.out.println("ConcreteProductB method01() ...");
}
public void method02() {
System.out.println("ConcreteProductB method02() ...");
}
}
/**
* 工厂接口类
* 定义了其子类必须实现的createProduct()方法
*/
interface IFactory {
// 运用了Java 中的泛型和反射技术
public abstract <T extends Product> T createProduct(Class<T> c);
}
/**
* 具体工厂类
*/
class ConcreteFactory implements IFactory {
public <T extends Product> T createProduct(Class<T> c) {
T product = null;
try {
product = (T) Class.forName(c.getName()).newInstance();
} catch (Exception e) {
e.printStackTrace();
}
return product;
}
}
public class 工厂方法模式 {
public static void main(String[] args) {
// 创建一个具体工厂
IFactory factory = new ConcreteFactory();
// 根据参数中具体产品的.class名称来决定创建的产品类型
Product product01 = factory.createProduct(ConcreteProductA.class);
Product product02 = factory.createProduct(ConcreteProductB.class);
product01.method01();
product01.method02();
product02.method01();
product02.method02();
}
}
简单工厂模式(静态工厂模式)
如果确定你的工厂类只有一个,我们可以简化掉抽象类,具体代码如下
public class Factory {
public static <T extends Product> T createProduct(Class<T> clz) {
Product product = null;
try {
product = (Product) Class.forName(clz.getName()).newInstance();
} catch (Exception e) {
e.printStackTrace();
}
return (T)product;
}
}
像这样的方式称为简单工厂模式(静态工厂模式),它是工厂方法模式的一个弱化版本。
Android源码中的工厂方法模式实现
ArrayList和HashSet
ArrayList和HashSet中的iterator方法相当于一个工厂方法,用于构造并返回一个具体的迭代器。
Activity的各种生命周期
具体请看 《Android源码设计模式解析与实战》这本书。
总结
优点:
- 在工厂方法模式中,用户只需要知道所要产品的具体工厂,无须关注具体的创建过程,甚至不需要具体产品类的类名。
- 在系统增加新的产品时,我们只需要添加一个具体产品类和对应的实现工厂,无需对原工厂进行任何修改,很好地符合了“开闭原则”。
缺点:
- 每次增加一个产品时,都需要增加一个具体类和对象实现工厂,使得系统中类的个数成倍增加,在一定程度上增加了系统的复杂度,同时也增加了系统具体类的依赖。