在java中,创建对象通常用构造函数来完成。如下:
public class Sample {
public Sample (){
//一些操作
}
}
然后当你创建对象的时候,你会这样写:
Sample a = new Sample();
这是java的常识。好了,现在假设你有一个父类Sample,子类SampleA和SampleB。你要在创建对象的时候,能根据不同条件返回不同的子类。你很自然的会这样写:
public class Sample {
public Sample (String flag){
if(flag==”A”)
return new SampleA;
if(flag==”B”)
return new SampleB;
}
}
假设现在需求变化了,你可能要根据条件返回10个子类。对于聪明而勤奋的你来说,这不是什么问题:
public class Sample {
public Sample (String flag){
if(flag==”A”)
return new SampleA;
if(flag==”B”)
return new SampleB;
if(flag==”C”)
return new SampleC;
//省略其他7个
}
}
虽然你有点头晕,不过毕竟完成老板的任务了。但你刚松了一口气,老板慢条斯理的对你说:明天我们的需求再次变化,我们需要返回一千个子类。你马上晕倒了……
为了完成老板的任务,你回家通宵达旦的翻资料。运气非常好的你——可能好到可以和AC米兰相比——注意到了在老式的jdbc代码里有这么一段:
class.forName(string driverName)……
没错,这是java的动态装载类机制。于是聪明的你马上动脑筋想到,是不是可以根据子类的类名来装载这个类,然后返回呢?没错,就这样做!
于是这个类就可以修改为:
public class Sample {
public Sample (String className){
return Class.forName(className).newInstance();
}
}
也就是说,如果你要返回一个SampleA,你只需传入这个参数:
”com.diegoyun.SampleA”
那么它就会返回一个对象,然后你在代码里把它转换成SampleA就可以了。
当然,你会意识到开始的思考可能有些欠缺。比如把Sample定义为一个接口,然后返回接口可能更好些。但不管怎样,仅仅几行代码,你就可以完成老板的任务,而不用写1000个子类的返回语句了。
之后你会在许多论坛看到这套解决方法,并且有个很学究的名字:
Factory模式
其实你内心知道,知道这个模式的名字没什么重要,重要的是:什么情况下可以使用这个模式?你会去查查字典:Factory(工厂),顾名思义,是制造大量相似产品的实体。注意这里的两个关键词:大量,和相似。当然你也知道了,在上述的情况下就可以使用。
不管怎样,你起码会使用Factory模式了。值得沾沾自喜一番。