2.3.4 可配置的简单工厂
现在已经学会通过简单工厂来选择具体的实现类了,可是还有问题。比如,在现在的实现中,再新增加一种实现,该怎么办呢?
那就需要修改工厂类,才能把新的实现添加到现有的系统中。比如现在新增加了一个实现类Impl3,那么就需要类似下面这样来修改工厂类:
- public class Factory {
- public static Api createApi(int type){
- Api api = null;
- if(type==1){
- api = new Impl();
- }else if(type==2){
- api = new Impl2();
- }
- else if(type==3){
- api = new Impl3();
- }
- return api;
- }
- }
每次新增加一个实现类都来修改工厂类的实现,肯定不是一个好的实现方式。那么现在希望新增加了实现类过后不修改工厂类,该怎么办呢?
一个解决的方法就是使用配置文件,当有了新的实现类后,只要在配置文件里面配置上新的实现类即可。在简单工厂的方法里面可以使用反射,当然也可以使用IoC/DI(控制反转/依赖注入,这个不在这里讨论)来实现。
下面来看看如何使用反射加上配置文件,来实现添加新的实现类后,无须修改代码,就能把这个新的实现类加入应用中。
(1)配置文件用最简单的properties文件,实际开发中多是xml配置。定义一个名称为"FactoryTest.properties"的配置文件,放置到Factory同一个包下面,内容如下:
- ImplClass=cn.javass.dp.simplefactory.example5.Impl
如果新添加了实现类,修改这里的配置即可,就不需要修改程序了。
(2)此时的工厂类实现如下:
- /**
- * 工厂类,用来创建Api对象
- */
- public class Factory {
- /**
- * 具体创建Api的方法,根据配置文件的参数来创建接口
- * @return 创建好的Api对象
- */
- public static Api createApi(){
- //直接读取配置文件来获取需要创建实例的类
- //至于如何读取Properties,还有如何反射在这里就不解释了
- Properties p = new Properties();
- InputStream in = null;
- try {
- in = Factory.class.getResourceAsStream(
- "FactoryTest.properties");
- p.load(in);
- } catch (IOException e) {
- System.out.println(
- "装载工厂配置文件出错了,具体的堆栈信息如下:");
- e.printStackTrace();
- }finally{
- try {
- in.close();
- } catch (IOException e) {
- e.printStackTrace();
- }
- }
- //用反射去创建,那些例外处理等完善的工作这里就不做了
- Api api = null;
- try {
- api = (Api)Class.forName(p.getProperty("ImplClass"))
- .newInstance();
- } catch (InstantiationException e) {
- e.printStackTrace();
- } catch (IllegalAccessException e) {
- e.printStackTrace();
- } catch (ClassNotFoundException e) {
- e.printStackTrace();
- }
- return api;
- }
- }
(3)此时的客户端就变得很简单了,不再需要传入参数,代码示例如下:
- public class Client {
- public static void main(String[] args) {
- Api api = Factory.createApi();
- api.test1("哈哈,不要紧张,只是个测试而已!");
- }
- }
把上面的示例代码输入到电脑里面,测试一下,体会体会。
联系客服