工厂方法模式的定义
工厂方法模式使用的频率非常高,其定义为:定义一个用于创建对象的接口,让子类决定实例化哪一个类。工厂方法使一个类的实例化延迟到其子类。
工厂方法模式的通用类图如图所示。
我们再来看看工厂方法模式四个角色
- Product抽象产品类,负责定义产品的共性,实现对事物最抽象的定义。
- Creator抽象创建类,也是抽象工厂。
- ConcreteCreator具体工厂类。
- ConcreteProduct具体产品类,是由具体工厂类完成创建。
抽象产品类代码如下
public abstract class Product{
//抽象方法
public abstract void method();
}
具体的产品类可以有多个,都继承与抽象产品类,其源代码如下
public class ConcreteProduct1 extends Product{
public void method(){
//业务处理
}
}
public class ConcreteProduct2 extends Product{
public void method(){
//业务处理
}
}
抽象工厂类负责定义产品对象的产生,源代码如下
public abstract class Creator{
public abstract <T extends Product> T createProduct(Class<T> c);
}
具体如何产生一个产品的对象,是由具体的工厂类实现的,代码清单如下
public class ConcreteCreator extends 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 ConcreteCreator();
Product product = creator.createProduct(ConcreteProduct1.class);
//继续处理业务
}
}
工厂方法模式的优点
- 良好的封装性,代码结构清晰。
- 扩展性非常优秀。
- 屏蔽产品类。
- 典型的接口框架。
工厂模式的使用场景
工厂方法模式是new一个对象的替代品,所以在所有需要生成对象的地方都可以使用。
Spring源码中有非常多的地方用到了工厂模式,接下来我们就一起查看一下Spring中非常重要的一个类AbstractFactoryBean
是如何利用工厂模式的。
// AbstractFactoryBean.java
// 继承了FactoryBean,工厂Bean的主要作用是为了实现getObject()返回Bean实例
public abstract class AbstractFactoryBean<T> implements FactoryBean<T>, BeanClassLoaderAware, BeanFactoryAware, InitializingBean, DisposableBean {
// 定义了获取对象的前置判断工作,创建对象的工作则交给了一个抽象方法
// 这里判断了Bean是不是单例并且是否已经被加载过了(未初始化但加载过了,这个问题涉及到Spring处理循环依赖,以后会讨论到)
public final T getObject() throws Exception {
return this.isSingleton()?(this.initialized?this.singletonInstance:this.getEarlySingletonInstance()):this.createInstance();
}
// 由子类负责具体创建对象
protected abstract T createInstance() throws Exception;
}
参考书目《设计模式之禅》