我们现在开发的项目一般都不会是完全从头开始开发,总有一些遗留代码和遗留程序可以参考。遗留代码往往文档也不全,即时有文档,也往往是过期的,因此文档的价值往往不大。
如果能利用好遗留代码,就可以大大提高开发的速度,并且能避免很多以前代码已经fix过的bug.
但是遗留代码往往非常庞大,内部的逻辑盘根错节,而且其实现的逻辑和目前要开发的逻辑仅仅是有部分相同,不能完全照搬。
能上有相似之处,但是不完全一致。
而且,在我们这个项目中,因为环境的原因(要联后台的很多台 server,我们找不到这些server),遗留代码可以编译,但是不能运行。
项目的时间压力也很大,怎样在最短的时间内理解和利用遗留代码的功能?总不能让遗留代码沉睡,而我们再去写一遍遗留代码已经实现的功能。
用好遗留代码有几点:
1、以数据结构为核心,仔细分析静态的数据结构。
从遗留代码中GUI所显示的最重要的数据开始入手,一层层去寻找数据的来源,
例如:股票 这个class.
一层层去寻找来源,最终找到 它是来自一个缓存好的DataSet中。而这个 dataSet 是调用 WebServices得到的。通过层层的寻找,对程序的数据结构有了大致的了解。
2、在大致理解遗留代码核心功能的基础上,抽取和简化其核心代码 编写 测试程序,以测试其功能。
举个例子,因为这是个GUI程序,对Form的管理,Form上所显示的数据的来龙去脉,就是其核心功能。挑选了一个简单的遗留代码中的GUI界面,编写一段逻辑打开这个界面,第一次在运行的时候总会存在异常的情况。找到抛出异常的地方,一般总是与服务器进行连接或者向服务器发请求的地方,在这些地方编写 Stub 程序,使其能正常运行,乍一看上去似乎工作量很大,其实工作量并不大,我大概只用了一天的时间就让这个界面运行了起来。运行起来以后好处很多:
(1) 观察程序动态运行时的状态,即系统的动态视图。
(2) 观察每个类在实际运行中的功能,考虑是否能使用这些类。
(3) 观察数据结构在每一步中所含有的数据值,推断出程序每一步真正的处理逻辑。
3、 没有GUI的遗留代码的利用。
例如,网络通信,配置数据的管理等都是没有GUI的遗留代码,也很重要。
举个例子: 用socket方式 连接后台的server,但是数据用某种格式来封装。socket 连接服务器的代码在遗留代码中已经存在了。 封装数据的格式在遗留代码中也存在了,但是都散落在各处,需要我们把它们找出来并且整合在一起。
找到socket连接server的代码后,编写一个测试程序使用这些代码,看看这些代码的工作方式是怎样的。
找到 封装数据格式的代码后,也编写一个测试程序来使用这些代码,创造一个要被发送的数据,即测试数据, 看看打包的过程是怎样的。
注意,代码中遇到用一些目前还不理解的class 成员变量的赋值就先用hardcoding 赋一个比较合理的值。
结果我们很快地让遗留代码工作起来了。
总结,遗留代码的利用关键是要让它们“活动”起来,成为能够工作的新生命,这就要求我们能抽取出它们有用的组织(代码),去除无法利用的旁支(编写stub, hardCoding给某些成员变量赋值 ),给它们粮食和水(编写测试数据),让它们跑跑看(编写测试程序)。