依赖是否可以作为一个独立的衡量软件质量的标准?
作者:网络转载 发布时间:[ 2013/5/21 14:44:39 ] 推荐标签:
这个争论的背景有点复杂。我尽量简化了说。
遗留系统有一个自制的service locator。是一个静态函数:
public static Object newObject(Class interfaceOrDefaultClass, Class[] parameterTypes, Object[] arguments);
使用起来是这样:
ImplFactory.newObject(MyInterface.class, new Class[]{int.class, String.class}, new Object[]{new Integer(1), "abc"});
这个函数会根据一个properties文件的配置来寻找一个带有制定构造函数的实现或者继承MyInterface的类。
比如,如果配置文件里面配置了
com.mycompany.MyInterface=com.mycompany.MyInterfaceImpl
而MyInterfaceImpl有这个构造函数:
public MyInterfaceImpl(int i, String s);
那么,MyInterfaceImpl会被使用。
而如果调用的时候用了一个缺省类,那么如果配置文件没有配置,会使用这个缺省类,比如:
ImplFactory.newObject(DefaultMyInterfaceImpl.class, new Class[]{int.class, String.class}, new Object[]{new Integer(1), "abc"});
这个自制的service locator无疑是非常原始,也是很难用的。为了准备向一个真正的ioc container过渡,我实现了一个dynamic proxy来封装ImplFactory。
使用起来如下:
MyInterface = serviceFactory.getMyInterface(1, "abc");
使用者只需要把getMyInterface这个函数声明在ServiceFactory这个接口中,可以直接使用getMyInterface()函数了。当然,这个serviceFactory是作为倚赖被注射进客户类的。以后,如果我们切换成了ioc容器,比如spring,只要增加一个dynamic proxy行了,客户代码基本不用动。
我的同事(ImplFactory是他亲手做的),对这个ServiceFactory不是太感冒。他认为这样做明显的好处是一个语法糖,语法漂亮一点而已。而因为ImplFactory本身已经是个抽象,ServiceFactory又是包在ImplFactory外面的抽象,那么"abstraction on top of abstraction"显得多余,或者说过度设计。我对这样一个在我看来毫无争议的问题有点不知道怎么说,不过我跟他说这样以后可以轻易地转移到别的ioc container上面,才说服了他。
ImplFactoryProxy具体怎么实现的,只要懂dynamic proxy的都会,我不赘述了。
这个实现里面,有一个问题,是怎么处理这个“缺省实现类”。在原来的代码里面,缺省实现类是硬编码在客户程序里的。而现在的用法里面,客户不能制定缺省实现类,所以这个信息需要额外提供给这个dynamic proxy。
我的做法仍然是注射,通过注射一个java.util.Map对象到这个ImplFactoryProxy类,来给这个类提供缺省实现信息。签名如下:
public class ImplFactoryProxy {
private final Map defaults;
ImplFactoryProxy(Map defaults) {
this.defaults = defaults;
}
...
}
写好了ImplFactoryProxy之后,我面临的下一个问题是怎么得到这个Map。我的做法是通过ClassLoader.loadResourceAsStream()来读入一个存在当前package里面的properties文件,然后调用Properties.load(inputStream)来得到Properties,这个Properties对象自然可以注射进ImplFactoryProxy了。
至此,希望你会说:没什么亚。大家都是这么做的。
不过,问题来了。
我的那个老资格的同事在review代码的时候看到这个ClassLoader.loadResourceAsStream,说:这个不行,我希望你改成用我们的PropFactory框架。
话说,这个遗留系统有一个相当强大(或者说复杂?)的读取property的框架,这个框架除了一般的按照key读取value,还支持树形的property,也是说,一个key可能对应一个子property map。(当然,还有其他功能)
用法是:
PropFactory.getInstance().getProperty("property file name").getPropertyValue("key");
这样的代码充斥整个code base。
我对这个框架的态度是相当保留的。主要的原因是我认为大多的配置值应该通过注射,而不是主动地去找PropFactory框架要。这种PropFactory.getInstance()的代码使单元测试变得困难,而且加大了系统耦合,随便一个模块要依赖于PropFactory。
而我在我的dynamic proxy中不使用PropFactory,除了上面的原因,还有以下几点:
1。我要的是一个简单的key-value map。根本不需要PropFactory提供的那么多功能。
2。Properties, ClassLoader.loadResourceAsStream都是标准jdk的东西,用起来也不难。而且我也做了一个IOUtils类来封装这部分代码:
IOUtils:
Properties loadProperties(ClassLoader loader, String resourceName);
3。我这个dynamic proxy相当的self contained。它基本上和现有的遗留系统除了ImplFactory没有任何其它关联。我也不希望引入任何不必要的依赖。
相关推荐
更新发布
功能测试和接口测试的区别
2023/3/23 14:23:39如何写好测试用例文档
2023/3/22 16:17:39常用的选择回归测试的方式有哪些?
2022/6/14 16:14:27测试流程中需要重点把关几个过程?
2021/10/18 15:37:44性能测试的七种方法
2021/9/17 15:19:29全链路压测优化思路
2021/9/14 15:42:25性能测试流程浅谈
2021/5/28 17:25:47常见的APP性能测试指标
2021/5/8 17:01:11