*续 第六章 当你编码时
2. 重构
a) 把软件开发比喻为修建建筑是不恰当的。因为修建建筑暗示了以下步骤:
建筑师绘制出蓝图;承包商挖掘地基,修建上层建筑、装修;房客入住,如有问题,就找维修人员。
但软件开发中,随着程序的演化,需要重新思考早先的决策,并重写部分代码,软件不是静态的事物。
软件开发更像园艺,或许特定的例程已变得太大,或是试图完成太多事情——它需要被一分为二,没有按照计划完成的事情需要被清除或修剪。
b) 重写、重做和重新架构合起来称为重构。
c) 应在何时进行重构
重复
非正交的设计
过时的知识
性能需要优化
d) 早重构,常重构。现实项目在时间上的压力往往会阻碍重构。这就需要管理人员能够正确认识重构的意义,如果现在没有进行重构,沿途修正问题将需要投入更多的时间,到那时将需要考虑更多的依赖关系。而且,需要重构的代码就像肿瘤,需要趁它还小时把它切除。
e) 怎样进行重构。就重构的核心而言,重构就是重新设计,根据新的事实、更深的理解、变化的需求等。但如果你无节制的撕毁大量代码,却可能带来更大的危害。关于怎样进行利大于弊的重构,有如下简单提示:
不要试图在重构的同时增加功能。
在开始重构之前,确保你拥有良好的测试。
采用短小、深思熟虑地步骤,并在每个步骤之后进行测试。
2. 易于测试的代码
a) 我们应该在一开始就把可测试性构建进软件中,并且在把各个部分连接在一起之前对每个部分进行彻底的测试(单元测试)。
b) 单元测试是在在受控的条件下对模块进行的彻底测试,通过单元测试能够更好地了解模块在广阔的世界上将怎样起反应。
c) 针对合约进行测试。编写测试用例,确保给定的单元遵守其合约。这将告诉我们两件事情:
代码是否符合合约;
合约的含义是否与我们所认为的一致。
通过强调针对合约进行测试,我们可以设法尽可能多地避免那些“下游的灾难”。
d) 测试你的软件,否则你的用户就得测试。测试是技术,但更是文化,不管所用语言是什么,我们都可以让这样的测试文化慢慢渗入项目中。
3. 邪恶的向导
a) 比如我们常常使用向导生成漂亮的界面和背后的大量代码,只要再加入具体的应用功能,软件就可以交付了,但这往往是愚弄自己,除非我们真的理解那些替我们制作的代码,否则就是在靠巧合编程。向导是一条“单行道”——它们为你制作代码,然后就走了,如果它们制作的代码不完全正确,或者情形变了,需要改变代码,那么就只能靠我们自己了。我们不是在反对向导,但如果你真的使用向导,就要理解它制作出的所有代码,这样才能很好地控制并维护自己的应用。
b) 虽说除了依赖我们不理解的向导,我们也在依赖其它很多不理解的事物,比如集成电路的量子力学、处理器的中断结构、用于进程调度的算法、系统提供的API等。但向导与它们是有区别的,因为向导生成的代码变成了我们应用的组成部分,它们一行一行地与我们编写的功能交织在一起,最后它不再是向导的代码,而变成了我们自己的代码,没有人应该制作自己不完全理解的代码。所以不要使用你不理解的向导代码。