工厂模式提供另外一种创建对象的方式,这种方式屏蔽了创建对象的细节,所以可以实现很多骚操作。下面的代码就是一个简单的工厂,通过传入全类名来创建对象。

1 原型工厂

1
2
3
4
5
6
7
public class BeanFactory {

    public <T> T getBean(String className)
            throws ClassNotFoundException, IllegalAccessException, InstantiationException {
        return (T) Class.forName(className).newInstance();
    }
}

测试代码

 1
 2
 3
 4
 5
 6
 7
 8
 9
10
11
public class Main {

    public static void main(String[] args)
            throws IllegalAccessException, InstantiationException, ClassNotFoundException {
        BeanFactory beanFactory = new BeanFactory();
        ArrayList arrayList = beanFactory.getBean(ArrayList.class.getName());
        System.out.println(arrayList.getClass());
        LinkedList linkedList = beanFactory.getBean(LinkedList.class.getName());
        System.out.println(linkedList.getClass());
    }
}

通过打印就能看到运行的毫无问题,你可能会感觉这个工厂没什么卵用,接下来我们对这个工厂稍加改造,让它变成一个可以选择创建单例或原型的工厂,下面是代码。

2 可以选择创建单例还是原型的工厂

 1
 2
 3
 4
 5
 6
 7
 8
 9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
public class BeanFactory {

    public static final String SINGLETON = "singleton";
    public static final String PROTOTYPE = "prototype";

    private HashMap cache = new HashMap(16);

    public <T> T getBean(String className, String mode)
            throws ClassNotFoundException, IllegalAccessException, InstantiationException {
        if (mode.equals(PROTOTYPE)) {
            return (T) Class.forName(className).newInstance();
        } else if (mode.equals(SINGLETON)) {
            Object o = cache.get(className);
            if (o == null) {
                o = Class.forName(className).newInstance();
                cache.put(className, o);
            }
            return (T) o;
        } else {
            return null;
        }
    }
}

然后我们来测试一下看看获取两个单例是否是相等的

 1
 2
 3
 4
 5
 6
 7
 8
 9
10
public class Main {

    public static void main(String[] args)
            throws IllegalAccessException, InstantiationException, ClassNotFoundException {
        BeanFactory beanFactory = new BeanFactory();
        ArrayList arrayList1 = beanFactory.getBean(ArrayList.class.getName(), BeanFactory.SINGLETON);
        ArrayList arrayList2 = beanFactory.getBean(ArrayList.class.getName(), BeanFactory.SINGLETON);
        System.out.println(arrayList1 == arrayList2);
    }
}

打印结果为 true,很明显,我们的单例工厂起效果了,这就能帮助我们少写很多单例模式的代码。不过一般都用 spring 框架,spring 功能齐全非常强大。