同行代码评审过程中的实践经验

数百万年前,猿从树上下来,进化出了对生拇指,最终,变成了人类。

我们以类似的眼光来看下强制性代码评审(Code Review):好像是一种能在软件开发这块广阔的领域里将人类从兽里分离出来的东西。

不过,我有时候会从我们的团队成员里听到下面这样的评论:

“这个项目的代码评审根本就是浪费时间。”

“我没有时间做代码评审。”

“我的项目发布延期了,都是因为我那懦弱的同事还没有做任何评审。”

“你能相信我的同事竟想让我在代码中改点东西吗?请向他们解释:如果我那最初的优雅代码受到任何方式改动的话,那就意味着宇宙微妙的平衡将要遭到破坏。”

为什么我们要做代码评审?

首先,让我们谨记为什么要做代码评审。对于任何专业的软件开发人员来说,最重要的目标之一是能够持续的提高他们的工作质量。即使你的团队里尽是优秀的程序员,你也不能将你自己与一个有能力的自由从业者区分开来,除非你能够作为一个团队工作。代码评审是达到这个目的的最重要方式之一。尤其,它们:

给予你第二双眼睛来找到做某些事的瑕疵和更好的方法。

确保至少有一个其他人员熟悉你的代码。

通过向新员工展示更有经验的开发者的代码来帮助训练他们。

通过让评审者和被评审者互相展示好的想法和做法以促进知识分享。

鼓励开发者在他们的工作中更加尽心尽力,因为他们知道自己的代码将来要被他们的的某个同事评审。

做彻底深入的评审

不过,如果不在评审工作上倾注一定的时间和精力,这些目标都是无法实现的。仅仅滚动浏览下patch,确保缩进正确、所有的变量采取小骆驼拼写法并 不能构成一次彻底的评审。受到业界的启发也可以考虑结对编程,这是一个相当流行的做法,但也在所有的开发时间上增加了100%的额外开销来作为代码评审工 作的基准。你可能会在代码评审中花费很多时间,但与结对编程相比,使用的总体工程时间仍少得多。

我认为花在代码评审工作上的时间应该是原开发时间的25%左右。例如,如果一个开发者花两天时间实现了个小项目,那么评审者应该花大致4个小时的时间来评审它。

当然,花在评审工作上多少时间并不是最重要的,只要评审能够准确无误的完成即可。特别地,你必须要能理解你正在审查的代码。这不仅仅意味着你只要懂 该代码所采用语言的语法即可,它还意味着你必须了解该代码如何适应于更大的应用环境、组件或库下。如果你不抓住每一行代码的全部含义,那么你的评审就不是 非常有价值的。这也是为什么好的评审都不可能非常快的完成:因为还要花时间去调查触发某个给定函数的不同代码路径,要去确保第三方API能够正确使用(包 括任何边缘情况),等等。

除了寻找你所审查的代码中的瑕疵或其它问题之外,你还应该确保:

包含所有必要的测试。

合适的设计文档已经写完。

甚至擅长写测试和文档的开发人员也并不总能记得在代码改动之后及时更新。在适当的时候来自代码评审人员的细微调整对于确保代码在随着时间的推移不会变质是至关重要的。

防止代码评审工作超负荷

如果你的团队强制要求做代码评审,那这是有风险的,因为你的代码评审工作可能一直积压,最终到无法管理的地步。如果你两周之内不做任何评审工作,你 可以很容易的花上几天时间来赶补它。不过这也意味着当你最终决定去处理它们的时候,你自己的开发工作将遭到一定的意外搁浅。这也使得做好评审工作更加困 难,因为正确的代码评审需要强烈、持续的脑力劳动,很难这样数日保持下去。

因此,开发者每天应该竭尽全力的清空他们的评审积压工作。一个方法是早晨的第一件事情就用来解决评审工作。在开始自己的开发工作之前先做完所有的优 秀评审工作,你可以防止以后的评审局面失控情况。有些人更喜欢在午休之前或之后或在一天结束后做审查工作。无论你什么时候做这些事情,通过将代码审查作为 正规的日常工作而不是作为一种分散注意力的工作,你可以避免:

没有时间处理你的评审积压工作。

因为你的评审工作还没做完而延迟项目的发布。

做出一些不再相关的评审,因为在此期间代码已经改动的非常多。

因为赶在最后一分钟处理它们而导致评审工作最终完成的很差。

写易于评审的代码

无法管理的评审积压工作也不能全怪评审人员。如果我的同事不管三七二十一的花费一周的时间来给一个大工程项目添加代码,那么他们发布的patch将真的很难评审,因为在一个阶段里有太多的工作要处理,代码的目的和底层架构体系也会很难理解。

这是将你的工作切割为一个个可管理单元之所以非常重要的众多原因之一,我们使用scrum管理方法,所以对我们来说合适的单元是重点。通过一起努 力,用单元来组织我们的工作,并提交仅与我们正在进行的某个单元相关的评审,我们可以写出更加易于审查的代码。你的团队可能使用另一种管理方法,但是原则 都是一样的。

为了写出易于评审的代码,还有一些其它的必备条件。如果要做出一些很棘手的架构决策,为满足评审者的要求,事先进行讨论是合理的。这将使得评审者更加容易的理解你的代码,因为他们将知道你在代码中试着达到什么目的以及怎么计划来达到该目的。这也有助于避免这样一种情况:在评审者提出一个不同的更好的方法后,你必须要重写你的大段代码。

在你的设计文档里项目架构应该要详细的描述。这无论如何都是很重要的,因为它能让一个新的项目成员很快的赶上进度并理解现有的代码库。它还能帮助评审者更好的做好自己的工作,这是另一个好处。单元测试也有助于向评审者说明组件应该如何使用。

如果你的patch里包含了第三方代码,请单独提交。例如当jQuery的9000行代码被插入代码中间时,要做好代码评审工作就难上加难了。

写出易于评审的代码的最重要步骤之一是给你的代码评审部分添加注释。这表示你可以自己浏览评审部分,并在任何你 觉得有助于评审者理解代码意思的地方添加注释。我发现这样的注释仅花费相对较少的时间(经常仅几分钟的时间)却能产生巨大的作用,能让代码评审工作完成的 更快、更好。当然,代码注释也有许多相同的优点,应该在合适的地方使用,但是通常来说评审注释更为明智。最后可以说是一个奖励吧, 研究表明,当开发者重新阅读和注释代码时,竟然发现他们自己的代码里有很多的瑕疵。

庞大的代码重构

有时有必要重构能影响许多组件的某个代码库。对于一个庞大的应用程序,这个过程可能花费好几天(甚至更久)且导致庞大的补丁。在这些情况下一个标准的代码评审工作可能是不切实际的。

最好的解决方法是递增式重构代码。在工作代码库的合理范围内找到能达到你目的的某个改动点。一旦改好了,review通过了,接着进行下一个改动, 直到整个重构工作完成。这个方法可能并不是每次都行得通,但是有想法和计划,在重构时要避免巨大的补丁通常是实际可行的。像这样来重构代码可能要花开发人 员更多的时间,但它同时也产生了更好的代码质量和更容易的评审工作。

如果真的实现不了递增式重构代码(这可能要说一些关于如何写好和组织好源代码的事情),一个可能的解决方案是当进行重构工作时用结对编程来代替代码评审。

解决争议

你的团队无疑是由一群聪明的专业人士组成。当大家对某个确定的编码问题观点不同时,基本上都会产生争议。作为一名开发人员,保持开放的心态,在你的评审者更倾向于一个不同的方法时要随时准备妥协。不要对你的代码持专有的态度,也不要带个人评审意见。如果仅仅是因为有人觉得你应该将一些重复的代码重构为一个可重复利用的函数时,这并不能表明你就不是一个有吸引力的、出色的和有魅力的人。

作为一个评审者,一定要机智。在改变建议之前,认真考虑下是否你给的提议真的更好或仅仅只是你个人风格问题。如 果你选择的战场集中在一些源代码中明显需要改进的区域,你将能获得更多的成功。说一些诸如“考虑下……可能是值得的”或“有人建议……”的话更适合,而不 是“连我的宠物仓鼠都能写出一个比这更高效的排序算法”。

如果达不到一个中间立场(即双方都不愿意妥协),那么就邀请一个双方都尊敬的第三方开发人员过来看看,让他们给出一些观点和建议。

文章转载自 开源中国社区 [http://www.oschina.net]

时间: 2024-10-29 13:28:14

同行代码评审过程中的实践经验的相关文章

F5调试代码的过程中,如何知道目前代码运行的位置

问题描述 F5调试代码的过程中,如何知道目前代码运行的位置,就是代码运行到哪行,请各位指教 解决方案 解决方案二:你知道F10和F11吗?在IDE里面试试她们是干什么的...解决方案三:引用1楼u012804018的回复: 你知道F10和F11吗?在IDE里面试试她们是干什么的... f10f11我会用,就是窗体已经按f5启动了,在ide调试f10,看不到窗体的变化,我想要通过操控窗体看到代码运行到哪行,正在学习别人的程序,有的功能找不到代码位置.解决方案四:引用2楼fyfy918的回复: Qu

DRaaS厂商:在评审过程中需评估的九个方面

当选择一家灾难恢复即服务供应商时,有很多方面需要进行比较,从性能到成本,到基础设施,再到可扩展性.以下这份清单将帮助您做出正确的选择. 近年来,灾难恢复即服务已经得到了大量的关注,因为这项技术为企业用户提供了远程数据中心的优势,而且还无需投入成本或建立一个远程设施.从理论上来说,DRaaS供应商让各种类型的企业用户拥有了远程备份和远程故障转移的功能. 尽管围绕着DRaaS有着众多的炒作,但是一些观察家指出那只不过是一个比较时髦的噱头而已,因为他们认为这项服务实施困难.具有较高隐形成本以及不同供应

我建设网站过程中的一些经验总结

中介交易 http://www.aliyun.com/zixun/aggregation/6858.html">SEO诊断 淘宝客 云主机 技术大厅 个人站长做网站要考虑到自己的资源和能力范围,要做到自己网站的特色.在做网站之前我们可以和其他的相同类型的网站做个比较.看一下自己的优势,内容上的来源是否充足.有没有吸引访客的地方,也就是说网页的亲和度怎么样. 网站建好了,我们要对自己的网站来一个体验,把自己当做是访客,看一下来这个网站是什么样的感受.就好比这个站是被人的,我们要对这个站可观的

谈谈SEO过程中内链布局的一些经验

摘要: 大家好,我是木子成舟.一直在跟大家交流SEO过程中的一些经验,也写过不少文章了,很多时候我都在会文章中谈到了内链布局,总是蜻蜓点水般的介绍内链布局的重要性,大家可能也 大家好,我是木子成舟.一直在跟大家交流SEO过程中的一些经验,也写过不少文章了,很多时候我都在会文章中谈到了内链布局,总是蜻蜓点水般的介绍内链布局的重要性,大家可能也没有充分的认识到内链布局是多么的重要.今天我要跟大家谈的就是内链布局的一些经验,希望通过我的这篇文章能让大家对内链布局引起足够的重视,然后帮助大家很好的完成网

基于 Rational Team Concert 定制代码评审流程及工具

引言 IBM Rational Team Concert(RTC)是 IBM Rational 面向软件交付技术的下一代协作平台-Jazz 平台上的软件开发环境,它通过集成工作项追踪.源代码控制和可配置的流程管理来实现敏捷开发.其中流程管理是其区别于一般版本管理工具的一个重要功能,它更注重于将对代码的管理融入到整个代码的开发周期和团队协作当中去. 本文基于 RTC 定制了一套代码评审流程.该流程能够帮助 Moderator 管理评审任务,分配评审任务给多个 Reviewer,以及追踪代码评审中发

JavaScript设计模式入门和框架中的实践

在编写JS和组装代码的过程中,运用一定的设计模式可以让我们的代码更加优雅.灵活. 下面笔者就结合诸如redux的subsscribe.ES6的class.vue里面的$dispatch.jquery里面的on/off来给大家简单介绍下设计模式在这些库.语法和框架中的使用. 设计模式解决的问题 设计模式并不是很玄乎的知识,很多同学在编写JS代码的时候已经在不经意间用了不少设计模式了. 笔者认为把设计模式单独抽象出来探讨,就和算法中抽象出来冒泡.排序一样,是为了描述一种常用的JS pattern.

从错误中汲取经验:打造Buffer过程中所学到的

Buffer是一款帮助你在Twitter.Facebook等平台上更高效的发布内容的应用,到目前我们已经有超过50万的用户了.两年前刚刚开始打造这个产品的时候,我们就已经做好了充分的思想准备去面对各种挑战,包括设计开发过程中会遇到的障碍以及可能犯的错误. 我们始终觉得,在项目当中犯错是在所难免的;只要能够从中学到一些东西,这些错误就能引导我们向正确的方向前进.从某种程度上讲,将我们的产品一点点推向成功的也许正是一路上所犯下的那些错误. 重要的设计原则 在开始讨论我们从错误当中学习到的那些经验之前

由Docker大规模运行中总结的六大实践经验

除非你在过去几年里一直生活在石器时代,否则你肯定知道容器和Docker.如果你是互联网极客的话,可能你已经准备在生产环境中使用Docker了. 一年前我也在尝试跟上技术更新的步伐,但以忙于交付原生态的系统结束.我见识到的虽让我某种程度上伤痕累累,但也让我收获颇丰,更重要的是让我意识到很多很流行工具的缺点.直到我们建立起一套不错的托管技术栈的时候,我的团队已经为融合这些技术开发了很多定制代码,我对这样的系统设计和运营很不满意,于是离开那里,成为了ContainerShip的联合创始人. 显然我可能

互联网产品优化过程中的经验

文章描述:互联网产品优化经验分享. 产品上线后,无论是否达到预期,都有非常大的优化空间,以下列一些产品优化过程中的经验,仅供参考: 一.建立产品监控体系 从宏观上来看产品要关注的大的点,并把其拆开,如果能实时监控最好,不能实时的全部放在报表中,每天看一次也可以,从中可以发现产品在大的点上是否出了问题! 举例:邀请回来的用户,有多少成功注册了,这里可以设置成一个转化率,如果某个点突然有较大的变化,能及时发现. 这里为什么说只列大的点呢!如果切分开,点就太多了,在作局部优化时可以把大点切分成小的点来