工厂模式相当于创建实例对象的new,我们经常要根据类Class生成实例对象,如A a=new A() 。工厂模式也是用来创建实例对象的,所以new时就要多个心眼,是否可以考虑实用工厂模式,虽然这样做,可能多做一些工作,但会给你系统带来更大的可扩展性和尽量少的修改量。设想一个场景:一个肉铺老板卖肉,因为刚开张生意冷清,也就先卖下猪肉吧。
类图如下:
原先我们可能会在客户端直接调用比如Pig asiaPig = new AsiaPig()之类的代码,但现在我们只需调用PigFactory.createPig(***)来达到对Pig实现类的创建,这样客户端程序中超类的代码和子类对象的创建代码解藕了。
public class PigFactory {
@SuppressWarnings("unchecked")
public static Pig createPig(String pigName) {
if ("AsiaPig".equals(pigName)) {
return new AsiaPig();
} else if ("AfricanPig".equals(pigName)) {
return new AfricanPig();
} else {
return null;
}
}
}
public class PorkStore {
private static void sendPork(String pigName) {
Pig africanPig = PigFactory.createPig(pigName);
africanPig.send();
}
public static void main(String[] args) {
sendPork("AsiaPig");
sendPork("AfricanPig");
}
}
这样做的另一个问题又出来了,随着if else的增多代码块变的越趋庞大,这时就可利用java的发射来进行改善了,调整如下:
package factoryMethod;
public class PigFactory {
@SuppressWarnings("unchecked")
public static Pig createPig(String pigNme) {
try {
Class animalClass = Class.forName(pigNme);
return (Pig)animalClass.newInstance();
} catch (ClassNotFoundException e) {
throw new RuntimeException("caught exception while found the class", e);
} catch (InstantiationException e) {
throw new RuntimeException("caught exception while instantiation", e);
} catch (IllegalAccessException e) {
throw new RuntimeException(e);
}
}
}
public class PorkStore {
private static void sendPork(String pigName) {
Pig africanPig = PigFactory.createPig(pigName);
africanPig.send();
}
public static void main(String[] args) {
sendPork("factoryMethod.AsiaPig");
sendPork("factoryMethod.AfricanPig");
}
}
共厂方法模式定义了一个创建对象的接口,但由子类决定要实例化的类是哪一个,让类把实例化推迟到子类。