实战遗留代码
什么是遗留代码?没有自动化测试的代码就是遗留代码,不管它是十年前写的,还是昨天写的。
关于遗留代码,《修改代码的艺术》迄今为止依然是在具体手法上讲得最好的一本书。
不过,这本书上来就直奔代码,还有一些东西是技法之外的。
搭建基础设施
做软件,没有自动化,基本上都算刀耕火织。关于基础设施,我曾写过一篇很长的文章,以我实际的一个项目为例,介绍了一些设施的基本样子。
那篇文章很长,具体到面对遗留代码,有哪些特别之处呢?
我们的目标是给没有测试的遗留系统增加代码,那么,那么增加代码覆盖率检查是一个不错的选择,各种语言都有自己的测试覆盖率方案。与单纯使用测试覆盖率不同的是,我们需要保证测试覆盖率只能提升,不能降低。所以,这里可能会略有一些开发的工作量。
此外,遗留代码的质量往往不高,除了测试覆盖率工具,我们还可以引入各种代码检查工具,同时,采用同上面类似的做法,保证各种错误只能减少,不能增加。
这里的基本想法很简单,不要在废墟上继续破坏。
补测试
理想中,我们要为所有代码补上测试,但是,这种想法不现实,很简单,欠账太多。
一个更为实际的做法是,任务驱动。根据要解决的问题,先把周边代码清理干净,然后再实现新需求。
动手清理之前,我们要先补写验收测试,这样做主要是为了保证我们不会产生大规模的破坏。对于比较复杂的场景,要补的测试可能会比较多,但请记住,这是欠账,昨日的帐,今天补当然会很痛苦。
补完验收测试,就该补单元测试了,补单元测试的做法有几种,无论哪种做法,我们都要先理解一下要动到的代码。
如果面对的函数比较小,理解起来比较容易,我们就可以直接为它补充单元测试。如果函数比较大怎么办呢?一次看懂所有的逻辑几乎就是一项不可能完成的任务,但通常,即便不能理解所有的代码,但至少我们可以理解一个片段。我们能做的就是把这个可以理解的片段提取到一个单独的函数里,然后,测试这个单独的片段。
在具体操作的层面上,经常出现的问题是,我们理解了这段丑陋的代码,脑子里常会不经意闪过这段代码未来的样子,所以,一动手就直奔目标样子而去,请停下来。先把这段完整的复制到待测函数里,然后给它写测试,测试通过之后再说重构的事。请记住,步子大了,容易扯到蛋。
这个片段函数做完之后,我们再回到原来的函数里,在原来片段的地方,调用这个新函数。然后,再继续理解,继续分解,继续补测试,继续重构,继续替换原有调用。如此N番,你会发现,那个复杂的大函数也不像原来那样不可理喻了,这时候,如果还需要,对这个函数,我们也可以如法炮制。
添加新代码
所有一切准备就绪,才是添加新代码的时机。
或许,这种做法会让曾经在开发中健步如飞的你有一种举步维艰的感觉,但请记住,曾经的健步如飞是你的错觉,因为当初的你并没有完成你该做的事情,那是欠账。
出来混,迟早要还的。
建议继续学习:
- 抵制代码重写 (阅读:4269)
- 如何避免重构带来的危险 (阅读:3759)
- 什么是重构,什么不是重构 (阅读:3508)
- 前端重构实践(一) —— 性能优化 (阅读:3201)
- 实践中的重构 (阅读:3101)
- 网站重构到底是什么,网站重构到底要多久 (阅读:2941)
- 关于重构和重写 (阅读:2605)
- 重构发现:指针操作问题 (阅读:2454)
- 网页重构应该避免的10大 CSS 糟糕用法 (阅读:2273)
- 代码重构方向原则指导 (阅读:1653)
扫一扫订阅我的微信号:IT技术博客大学习
- 作者:dreamhead 来源: 梦想风暴
- 标签: 遗留代码 重构
- 发布时间:2012-07-19 12:22:40
- [72] Twitter/微博客的学习摘要
- [64] find命令的一点注意事项
- [63] Go Reflect 性能
- [62] android 开发入门
- [62] IOS安全–浅谈关于IOS加固的几种方法
- [60] 流程管理与用户研究
- [60] Oracle MTS模式下 进程地址与会话信
- [60] 如何拿下简短的域名
- [57] 图书馆的世界纪录
- [57] 【社会化设计】自我(self)部分――欢迎区