先说说简单工厂的缺点:在简单工厂模式中,工厂类集中了创建实例对象的逻辑. 这就是缺点。为什么这么说呢?如下所示:
interface Simple{
}
第一种写法:
class SimpleFactory{
public static Simple getSimpleInstance(){
return new SimpleImpl();
}
}
对于这种写法,先不说上面的那条缺点,单是这种写法就已经很有缺点了,它只能产生一个具体的子类实例对象,不利于程序的扩展。
第二种写法:利用反射可以根据传进来的类名产生实例对象
class SimpleFactory{
public static Simple getSimpleInstance(String name){//将子类的名字传递进来
try{
return (Simple)Class.forName(name).newInstance();
}catch(Exception e){
throw new RuntimeException(e);
}
}
}
这一种可以灵活的实现产生不同的子类对象,但是它的缺点就是上面说的集中了创建实例对象的逻辑,再说得具体点,就是如果两个子类对象的创建过程不相同该怎么办?
比如现在有这种需求:只有在满足某种特定的条件下才创建 SimpleImpl2的实例对象, 但是创建SimpleImpl的实例对象的时候不需要满足任何条件(就如代码写的那样)。
这还不容易解决?改改代码呗,增加if判断,根据传进来的类名判断如果是SimpleImpl就直接创建,如果类名是SimpleImpl2,就先对它进行一些必要的操作再进行创建,这样就搞定了。如果我有SimpleImpl3呢?那就继续加判断呗!但是这样很不爽,因为破坏了原有的代码结构。在不破坏原有代码结构的前提下,这种写法就做不到了,因为它把创建实例对象的逻辑给定死了。
基于以上的缺点,就出现了工厂方法模式(又称为多态工厂模式)。
什么是工厂方法模式?
大白话讲就是定义一个工厂接口,它不再创建具体的实例对象,而是将创建实例对象的工作交给它的子类工厂去做。如下所示:
定义一个抽象的工厂:
abstract class SimpleFactory{
public abstract Simple getInstance();
}
产生SimpleImpl对象的具体工厂
class SimpleImpl extends SimpleFactory{
public Simple getInstance(){
return new SimpleImpl();
}
}
产生SimpleImpl2对象的具体工厂
class SimpleImpl2 extends SimpleFactory{
public Simple getInstance(){
//这里可以写要执行的代码....
return new SimpleImpl2();
}
}
以上就是工厂方法模式的简单介绍。它的优点是可以在不修改原有代码结构的情况下,产生新的对象。比如现在我如果想要产生SimpleImpl3对象的话,就只需要定义一个产生SimpleImpl3对象的工厂类即可,而不需要再原来的工厂代码上做改动。
这其实也是我们所讲的 "开放--封闭" 原则(就是说程序可以进行扩展,但是以前写的代码尽量不进行改动).