(Regression)。这时,重构会起到与其初衷相反的作用。所以我们应该尽可能多地增加单元测试。有些老产品,旧代码,可能没有或者没有那么多的单元测试。但我们至少要在重构前,增加对要重构部分代码的单元测试。基于重构目的的单元测试,应该遵循以下的原则(见《重构》第4章:构筑测试体系):
- 编写未臻完善的测试并实际运行,好过对完美测试的无尽等待。测试应该是一种风险驱动行为,所以不要去测试那些仅仅读写一个值域的访问函数,应为它们太简单了,不大可能出错。
- 考虑可能出错的边界条件,把测试火力集中在哪儿。扮演“程序公敌”,纵容你心智中比较促狭的那一部分,积极思考如何破坏代码。
- 当事情被公认应该会出错时,别忘了检查是否有异常如期被抛出。
- 不要因为“测试无法捕捉所有Bug”,就不撰写测试代码,因为测试的确可以捕捉到大多数Bug。
- “花合理时间抓出大多数Bug”要好过“穷尽一生抓出所有Bug”。因为当测试数量达到一定程度之后,测试效益就会呈现递减态势,而非持续递增。
说到《重构》这本书,其实在每个重构方法中都有“作法(Mechanics)”一段,在重构的实践中按照上面所述的步骤进行是比较稳妥的,同时也能避免很多不经意间制造的回退出现。
4. 要求提交代码前做Code Review,而开发人员不做,或敷衍了事,怎么办?
如果每个开发人员都是积极主动的,Code Review的作用能落到实处。但如果不是呢?团队管理者需要一些手段促使其有效地进行Code Review。首先,我们采用的Code Review有2种形式,一是Over-the-shoulder,也就是2个人座在一起,一个人讲,另一个人审查。二是用工具Code Collaborator来进行。无论哪种形式,在提交代码时,必须注明关于审查的信息,比如:审查者(Reviewer)的名字或审查号(Review ID,Code Collaborator自动生成),每天由一名专职人员来检查Checklist中的每一条,看是否有人漏写这些信息,如果发现会提醒提交的人补上。另外,某段提交的代码出问题,提交者和审查者都要一起来解决出现的问题,以最大限度避免审查过程敷衍了事。
博主Inovy在某个评论说的很形象:“木(没)有赏罚的制度,就是带到厕所的报纸,看完就可以用来擦屁股了。”没有奖惩制度作保证,当然上面的要求没有什么效力。所以,当有人经常不审查就提交,或审查时不负责任,它的绩效评定就会因此低一点,而绩效的评分是跟每年工资涨落挂钩的。说白了,可能某个人会因为多次被查出没有做Code Review就提交代码,而到年底加薪时比别人少涨500块钱。
5. 软件研发到底需不需要文档?
软件研发需要文档的起原可能有2种,一是比较原始的,需要文档是为了当开发人员离职后,企业需要接手的人能根据文档了解他所接手的代码或模块的设计。二是较高层次的,企业遵从ISO9001质量管理体系或CMMI。
对于第一种,根源可能来自于两个方面:
- 原开发人员设计编码水平不高,其代码可读性较差。
- 设计思想和代码只有一个人了解,此人一旦离职,无人知道其细节。
在编码前写一些简单的设计文档,有助于理清思路,尤其是辅以一些UML图,在交流时也是有好处的。但同时,我们也应该提高开发人员的编码水平增加其代码的可读性,比如增强其变量命名的可读性、用一些被大家所了解的设计模式来替代按自己某些独特思路编写的代码、增加和改进注释等等,以减少不必要的文档。另外推行代码的集体所有权(Collective Ownership),避免某些代码只被一个人了