前阵子去买了两本书,《重构》和《修改代码的艺术》。根据高人指点,决定先读《修改代码的艺术》。
1.中文译名问题
本书英文原名《Working Effectively with Legacy Code》,大体意思是有效的面对遗留代码,但是不知道为何被翻译为修改代码的艺术,而我觉得本书所讲述的内容并不是关于修改代码的具体细节,更没有太多艺术感。但是这丝毫不影响这本书的价值,以及方法的可行性。
2.本书的主要内容提前说明一个概念,遗留代码:已有的项目代码,不管是你的,还是他人的,不管是维护中的,还是开发中的,总之是已经写好的代码,称为遗留代码。当代码被写下来,编译通过,并checkin后,它就变成了遗留代码。
本书主要讲的是在对遗留代码进行修改前,要进行的准备工作,即安置单元测试,保护当前代码的已有行为,并在此基础上引入测试驱动开发。
如何把测试安置到遗留代码中,并不是一件简单的事情,本书正是为了让我们做到这件不简单的事情而准备的,因此把本书看作测试驱动开发实践的前哨和准备也不为过。
3.安置测试难在哪里?
简单的单元测试说白了很简单,实例化一个类,然后调用被测试方法,然后验证测试结果。但现实很复杂,一个不良的类很难实例化,当你实例化这个类的时候,往往要实例化另外一个被依赖的类,如果该类涉及I/O,网络,数据库什么的,难道还要为了单元测试配置环境不成?
另外一个难处是难以调用被测试方法,因为该方法可能会显性的(通过参数)或者隐性的(全局变量)依赖于一些难以实例化的类和对象。
最后一个难处是如何感知测试结果并验证,有返回值的函数还可以判断个返回值什么的,没有返回值的函数怎么才知道它是正确的呢?
以上这三个问题,我是没想到如何解决,在我早期接触单元测试这个概念的时候。
4.如何安置测试要安置测试首先必须找出测试点,当难以用相关技术在测试点安置测试的话,采取退一步的策略是比较划算的。
当确定测试点后,为了在测试点安置测试,首先要进行的就是解依赖。解依赖的目的是分解出当前的类对其他难以实例化的类和全局变量过分紧密的依赖,使得被测试的类容易在测试工具中实例化,被测试方法容易调用。
要解依赖,就要利用被测试代码中的接缝,在测试工具中分离出难以实例化的依赖。书中对接缝是这样定义的:“是指程序中的一些特殊的点,在这些点上你无需做任何修改就可以达到改动程序行为的目的。”。
举一个接缝的简单例子,如虚函数,你无需对原来的代码做任何改动,就可以通过继承并重载来改变程序的行为。
遗留代码也许并没有多少接缝,因此为安置测试而解依赖的主要目的就是将依赖放置到接缝下,并在测试工具下改变接缝的行为,使得能够实例化被测试类,以及调用被测试方法,并通过接缝感知和验证测试结果。
总的来说,安置测试的过程如下:
4.1找出测试点
4.2解依赖:用接缝包住依赖
4.3在测试工具下改变接缝行为
4.4简单的执行单元测试:实例化类,调用被测试方法
4.5验证测试结果,通过接缝验证测试结果(需要的话)
5.接缝(解依赖技术)本书一共给出24种解依赖技术,不过我感觉其实很多是已有方法的变种,因此总结了一下,常用的有4种:虚函数并子类化,设置并替换,获取方法,参数化方法。特殊的有2种:参数包装,方法对象。
6.《修改代码的艺术》,这里有什么好修改的?这本书能和修改细节扯上边的地方,就是解依赖技术了。为了提供接缝,就必须在没有测试保护的情况下对遗留代码进行修改,因此最好采取尽量安全的修改方式。本书给出了为了解依赖,制造接缝而如何进行安全修改的修改细节,当然简单的说无非就是签名保持和剪切粘贴之类的了。
7.我的实践不动指头不读书。我用当前的项目中我写的一个类进行了试验,为它的每个public函数安置了多个单元测试,解依赖的运用还算正常,掌握得不是很好。
我选择的测试框架是,CppUnitLite,这个比CppUnit易用,作者本身也承认了。
配置测试工程:建立一个exe工程,将产品工程的配置复制过来,并添加对测试框架的依赖。
为了方便分离测试代码和产品代码,一个好的建议是:产品的工程只做成一个壳子,而将相关的逻辑部分编译成一个静态库,这样测试工程和产品工程都可以使用,并且两者是分离的。
posted on 2008-01-11 23:55
LOGOS 阅读(3134)
评论(6) 编辑 收藏 引用