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