我们为什么要做代码审查?
任何专业的软件开发人员其最重要的目标之一就是要不断提高自己的工作质量。但是只有团队协作才能力往一处使,劲往一处用,才能提高。代码审查是实现这一目标最重要的途径之一。
代码审查可以:
1、从另一个角度发现缺陷和更好的解决办法。
2、确保至少另外还有一人熟悉你的代码。
3、通过翻阅资深开发人员的代码,帮助培训新员工。
4、促进知识共享。
5、激励开发人员更好地写代码、解决代码中的问题,以免在审查时被别人揪出来。
代码审查要彻底
然而,除非能实实在在彻彻底底地在代码审查上花时间和精力,否则上述目标是很难实现的。
我的建议是25%的原始开发时间应该花在代码审查上。举个例子,如果一个开发人员需要用两天时间来实现某个程式,那么就应该花大约4小时进行审查。
当然时间并不是最重要的,关键是要看你能否正确审查代码。你必须了解你正在审查的代码。这意味着你不仅仅要知道它的的语法,还必须理解代码是如何融入应用程序这个大环境下,成为组件或库的一部分。如果你不能把握每一行代码的含义,那么你的审查就不到位,也不会非常有价值。这也是为什么良好执行的代码审查,大多不可能迅速被完成:因为我们需要时间来研究各种代码,如能触发给定功能以确保第三方API正确使用的代码。
在审查时,除了要寻找代码缺陷和其他问题,你还应该确保:
- 囊括所有必要的测试。
- 已经写入了恰当的设计文档。
即使是那些擅于写测试和文档的开发人员,也会在改变代码的时候忘记更新。代码评审时就应该确保这些资料不会随着时间而变得毫无用处。
避免过度的代码审查
开发人员应该努力清空积压的审查任务。有一种方法是在早上代码审查,在开始自己的开发工作之前先搞定审查任务。当然你也可以午饭前后或者是一天结束之时审查代码。总而言之,你应该将代码当作是日常工作的一部分,而不是工作的负累,所以你应该避免:
- 没有时间处理积压的审查任务。
- 由于审查的没有完成而导致了延迟发布。
- 傻乎乎地再去审查已经不相干的代码,在交给你之后已经被改的面目全非。
- 因为时间紧迫急急忙忙地走个过场。
编写可审查的代码
出现代码积压而失控的问题,审查人员并不是唯一一个需要负责的人。举个例子,如果你的同事花了一周时间为一个大型程序添加了乱七八糟的代码,那么发布的补丁就会变得很难审查,有太多的内容需要理解和钻研。甚至于连代码目的和基本架构都看得云里雾里。这是写代码的不对了。
在编写可审查的代码之前,还需要做一些准备。如果需要做一些棘手的架构决策,那么最好和审查人员先讨论一番。这将能让你的代码更容易审阅和理解,因为他们提前已经知道你想实现什么以及计划如何实现。这也可以避免,要是审查人员之后提出一个截然不同又更好的方法,而导致你不得不重写一大片代码的情况。
项目架构应该在设计文档中详细描述。这很重要,因为它能让新的项目人员更快地理解现有的代码库,还能有助于审查人员更好地完成他们的工作。此外,单元测试能让审查人员更好地理解各个组件的使用。
如果在你的补丁中还包含了第三方代码,那么单独提交。试想一下,要是代码中间插进去9000行jQuery,是不是大大增加了审查的难度!
创建可审查代码最重要的步骤之一就是给你的代码审查做注释。这需要你自己预先审查过,然后在你认为有助于审查人员理解的地方添加注释。我发现,注释后的代码审查所需的时间相对较短(通常只需几分钟)。当然,代码注释还是应该酌情使用。此外,有研究表明,开发人员自己在给代码注释的时候也会发现许多存在的缺陷。
代码重构
有时候,我们必须重构代码库。如果恰巧碰到的是一个大型的应用程序,那可能就会需要几天的时间(甚至更多),同时会产生大量的补丁。在这种情况下,想要做到标准流程的代码评审可能是不切实际的。
最好的解决办法是逐步重构代码。先给定一个合理范围,确定相应的代码库,然后朝着目标方向做整改和重构。第一部分完成之后,审查并发布,然后进行第二部分的重构……,直到全部完成。这种阶段式的方法可能并不总是可行的,但是如果我们在思考和规划时使用这样的方法,可以避免重构时大规模的单片补丁。当然这种方式可能需要的重构时间更多,但是也会产出更高质量的代码,以及更加轻松的审查过程。
如果增量重构代码还是不可行,那么还有一个更好的办法就是结对编程。