Define an interface for creating an object,but let subclasses decide which class to instantiate.Factory Method lets a class defer instantiation to subclasses.
工厂方法模式使用的频率非常高。定义一个用于创建对象的接口,让子类决定实例化哪一个类。工厂方法使一个类的实例化延迟到其子类。
工厂方法模式的通用类图:
抽象产品类代码:
public abstract class Product{
public void method1(){
//业务处理代码
}
public abstract void method2();
...
}
具体的产品类代码:
public class ConcreteProduct1 extends Product{
public void method2(){
//业务处理代码
}
...
}
public class ConcreteProduct2 extends Product{
public void method2(){
//业务处理代码
}
...
}
抽象工厂类代码:
public abstract class AbstractFactory{
//生产产品方法,这里使用了泛型
public abstract <T extends Product> T createProduct(Class<T> c);
...
}
具体的工厂类代码:
public class ConcreteFactory{
//生产产品方法,这里使用了泛型
public <T extends Product> T createProduct(Class<T> c){
Product product = null;
try{
//这里用到了Java的反射机制来产生类对象
product = (Product)Class.forName(c.getName).newInstance();
}catch(Exception e){
//异常处理代码
}
return (T)product;
}
...
}
工厂方法模式的优点:
1.封装性良好,代码结构清晰,易于阅读;
2.扩展性也非常良好,面向接口编程,可以很好的实现扩展;
3.屏蔽了产品类的实现。
我们再来看一下工厂方法模式的试用场景:
下面我们来看一下工厂方法模式的扩展:
第一个是简单工厂方法模式,即直接实现工厂类,省略掉抽象的工厂类;
第二个就是实现多个工厂类,不借助于Java的反射机制,而是每个工厂类生产具体的产品;
由于上两个扩展都比较实现,就不给出代码实现。
第三个替代单例模式,代码如下:
单例类:
public class Singleton{
//避免产生多个实例
private Singleton(){}
...
}
单例类工厂:
public class SingletonFactory{
private static Singleton singleton = null;
static{
try{
Class c = Class.forName(Singleton.class.getName());
Constructor con = c.getDeclaredConstrunctor();
//这里要设置一下无参构造函数可访问性
con.setAccessible(true;
singleton = (Singleton)con.newInstance();
}catch(Exception e){ //异常处理 }
}
public static Singleton getSingleton(){
return singleton;
}
...
}
此处注意,这种单例模式实现不是线程安全的,注意使用场景。
第四种,就是实现延迟初始化,代码如下:
public class Factory{
private static final Map<String,Product> map = new HashMap();
public static synchronized Product createProduct(String type) throws Exception{
Product product = null;
if(map.containsKey(type) && map.get(type) != null){
product = map.get(type);
}else{
if(type.equals("product1")){
product = new ConcreteProduct1();
}
...
map.put(type,product);
}
return product;
}
...
}
等等,还有很多的工厂方法模式的扩展。。。
总之,工厂方法模式在项目中应用广泛,使用频繁。例如Spring等框架中就使用到了工厂方法模式。该模式几乎尽人皆知,使用方便,但是用的好久不是那么容易的啦。工厂方法模式还可以跟其他模式混合使用,变化无穷,今天的工厂方法模式就到这里了。