原作者:Trisha Gee

Code Review 的时候,每个人都会关心最佳实践,但最坏的实践有时可能会更有启示意义。

Code Review是研发团队必不可少的,但并不总是正确的。这篇文章指出了所有开发者在Code Review时或提交拉取请求时可能都会遇到的一些常见的错误模式,并对这些错误模式进行了总结:

错误模式:挑毛病

想象一下下面的场景。代码作者花了几个小时,甚至几天的时间来创建他们认为最有效的解决方案。他们考虑了多种设计方案,并选择了看起来最相关的路径。他们考虑了现有应用程序的架构,并在适当的地方进行了修改。然后,他们将自己的解决方案以拉动请求的形式提交,或者开始了代Code Review 过程,他们收到的专家反馈是:

  • "你应该使用标签,而不是空格。"
  • "我不喜欢这部分的大括号在哪里。"
  • "你的文件末尾没有空行。"
  • "你们的词库是大写的,应该用句子大写。"

虽然新的代码要与现有代码的风格保持一致是很重要的,但这些东西几乎不需要人工审核员来完成。人工审核员的成本很高,而且可以完成计算机无法完成的事情。检查是否符合风格标准是计算机可以轻松完成的事情,这就分散了代码审核的真正目的。

如果开发人员在代码审核过程中看到很多这样的注释,说明这个团队要么是没有风格指南,要么是有了风格指南,但检查风格还没有实现自动化。解决的办法是使用checkstyle等工具来确保风格指南已经被遵循,或者使用sonarqube来识别常见的质量和安全问题。而不是依靠人工审核员来警告这类问题,持续集成环境可以做到这一点。

有时,如果没有代码指南,或者内部代码风格随着时间的推移而变化,在不同的部分有不同的风格,那么这种自动检查可能会很困难。在这种情况下,有一些方法可以应用自动检查。例如,一个团队可以同意做一个单一的提交,应用约定的代码风格,并且不包含其他的更改。或者一个团队可以约定,当一个文件因为bug或功能而被更改时,该文件也会被更新到新的样式,而自动工具可以被配置为只检查更改过的文件。

如果一个团队有多种代码样式,而它没有办法自动检查样式,也容易落入下一个陷阱。

错误模式:不一致的反馈

每一个被邀请审阅代码的开发者,至少要多邀请一个意见,而且可能更多。每个人都可以同时持有不止一种意见。有时,Code Review 可能会陷入审查者之间关于不同方法的争论,比如说是使用流还是经典的for循环最好。如果团队成员对同一段代码有不同的意见,那么开发人员应该如何进行修改,结束审阅,并将代码推送到生产中?

即使是一个审稿人的想法也很容易发生变化,可能是在一次审稿中,也可能是在一系列的审稿中。在一次审阅中,一个审阅者可能会催促作者确保使用O(1)读操作的数据结构,而在下一次审阅中,审阅者可能会问为什么不同的用例会有几个数据结构,并建议通过单一结构进行线性搜索来简化代码。

当一个团队对自己的 "最佳实践 "是什么样子的没有一个明确的想法,当团队还没有弄清楚自己的优先级是什么的时候,这种情况就会出现:

  • 代码是否应该向着更现代的Java风格发展?还是更重要的是代码的一致性,因此,继续到处使用 "经典 "构造?
  • 在系统的所有部分中,对数据结构进行O(1)读操作是否重要?还是有些部分的O(n)可以接受?

几乎所有的设计问题都可以用 "这要看情况 "来回答。为了对答案有一个更好的想法,开发人员需要了解他们的应用和团队的优先级。

错误模式:最后一分钟的设计变更

开发者在Code Review 过程中最让人士气低落的反馈是:当评审者从根本上不同意方案的设计或架构,并强行完全重写代码时,要么通过一系列的评审来逐步完成(见下一节),要么粗暴地拒绝代码,让作者重新开始。

Code Review 不是评审设计的正确时机。如果团队按照经典的 "网关式 " Code Review ,那么在最后一步让另一个开发人员看代码之前,代码应该是可以工作的,所有的测试都应该是通过的。在这一点上,几个小时、几天,甚至可能是几周(虽然我真的希望不是几周;Code Review 应该是小事一桩,但这是另一个话题)的努力已经花在了被审查的代码上。在Code Review 中指出底层设计是错误的,这是在浪费大家的时间。

Code Review 可以作为设计审查,但如果这是Code Review 的意图,那么审查应该在实现之初就进行。然后,在开发人员还没有走得太远之前,他们可以把自己的想法勾勒出来,也许会有一些存根类和方法,以及一些有意义的名称和步骤的测试,也许还可以提交一些文字或图表,以便让团队成员对将要采取的方法进行反馈。

如果团队成员在关口审查中发现了真正的展示性设计问题(也就是说,当代码完成并运行时),团队应该更新流程,以便更早地定位这些问题。这可能意味着要做其他类型的审查,比如上一段中建议的审查,白板上的想法,配对编程,或者与技术负责人讨论建议的解决方案。在最后的Code Review 中发现设计问题是对开发时间的浪费,也是对代码作者的极大打击。

错误模式:乒乓球 Reviews

在一个理想的世界里,作者会提交代码进行评审,评审人员会提出一些明确的解决方案的意见,作者提出修改建议并重新提交代码,评审结束,代码就会被推送。但如果这样的事情经常发生,谁还能说得清 Code Review 的过程是有道理的呢?

在现实生活中,经常出现的情况是这样的:

  1. 一个Code Review开始了。
  2. 一些审稿人提出了几个建议:有的小而容易,有的蓬头垢面,没有明显的解决方案,有的复杂。
  3. 作者做了一些修改:至少是简单的修改,或者说是几处修改,力求让审稿人满意。作者可能会向审稿人提出问题来澄清一些事情,或者作者可能会提出意见,解释为什么没有做出特定的修改。
  4. 审稿人回来后,接受一些更新,对其他的修改提出进一步的意见,找到他们不喜欢的地方,回答问题,并在审稿中与其他审稿人或作者争论他们的意见。
  5. 代码作者做更多的修改,增加更多的评论和问题,以此类推。
  6. 审稿人检查修改,提出更多的意见和建议,以此类推。
  7. 步骤5和6重复进行,或许永远都是这样。

在这个过程中,理论上来说,修改和批注应该向着零的方向下降,直到代码准备好为止。最郁闷的情况是,每一次迭代都会带来至少和已经结束的旧问题一样多的新问题。在这种情况下,团队就进入了 "Code Review 的无限循环"。发生这种情况的原因有很多:

  • 如果审稿人吹毛求疵,如果审稿人给出的反馈不一致,就会出现这种情况。对于陷入这些习惯的审稿人来说,有无限多的问题需要找出,有无限多的意见需要提出。

  • 当审稿时没有明确的审稿目的,或者审稿时没有准则可循,就会出现这种情况,因为这样一来,每个审稿人都会觉得每一个可能出现的问题都必须找出来。

  • 当不清楚审稿人的评论对代码作者的要求是什么时就会发生。是不是每一条评论都意味着必须要进行修改?所有的问题是否都暗示着代码没有自证,需要改进?还是有些评论仅仅是为了教育代码作者下一次,而提出问题只是为了帮助审稿人理解和学习?

评论应该被理解为阻止者或不是阻止者,如果审稿人决定代码需要修改,他们需要明确说明代码作者应该采取什么行动。

同样重要的是,要明白由谁来决定审核是否 "完成"。这可以通过任务清单上的检查项目来实现,也可以由个人授权说 "足够好 "来完成。通常需要有一个人能够打破僵局,解决分歧。这个人可能是高级开发人员、领导或者是架构师,甚至是团队中的代码作者,因为在团队中,他们之间的信任度很高。但是,在某些时候,需要有人说 "评审结束了 "或者 "当这些步骤完成后,评审就结束了。"

错误模式:幽灵审查

在这里我承认我最容易犯的反常的地方:幽灵化。无论我是审阅者还是代码作者,在代码审阅中都会出现一个点(有时就在开始的时候!),在审阅过程中,我根本就没有回应。也许有一个重要或有趣的功能被要求我审阅,所以我决定把它留到 "更好的时候",等我可以 "真正好好看一看 "的时候再做。又或许是Review的量大,我想留出充足的时间。又或许是我是作者,在迭代(或二十次)后,我就是无法面对阅读和回复评论了,所以我决定等 "等我的脑袋想好了再来"。

听起来是不是很熟悉?

不管是什么原因,有时在审查过程中有人根本没有反应。这可能意味着在这个人看完代码之前,审查工作就已经死气沉沉了。这是一种浪费。即使有人在创建一个资产(新代码)上投入了时间,但在它投入生产之前,它并没有增加价值。事实上,当它在代码库中越来越落后于其他代码库的时候,它很可能已经腐烂了。

有几个因素会导致幽灵审查。庞大的代码审核量是一个因素,因为谁愿意去翻阅几十个或几百个修改过的文件?不重视Code Review 是另一个因素,因为不重视Code Review 是真正的工作或交付成果的一部分。困难的或令人沮丧的Code Review 经历是另一个主要因素。没有人愿意停止编码(开发人员通常喜欢的东西),去参加一项耗费时间和破坏灵魂的活动。

以下是解决幽灵审查的建议:

  • 确保Code Review 的规模要小。每个团队都要制定出自己的定义,但这将是几个小时或几天的复审工作,而不是几周的时间。
  • 确保Code Review 的目的很明确,审查人员应该找的东西很清楚。当范围是 "找到代码中可能存在的任何问题 "时,很难激励自己去做一件事。"
  • 在开发过程中留出时间来做Code Review 。

最后一点可能需要团队的纪律性,或者团队可能希望通过(例如)通过目标或任何用来决定开发人员的生产力的机制来奖励良好的Code Review 行为来鼓励允许时间。

你的团队能做什么?

对于研发团队,专注于创建一个行之有效的Code Review流程。我在我的博客上写过这方面的内容,但想在这里分享一下这个过程的一部分:

  • 在进行Code Review 时,有很多事情需要考虑,如果开发人员在每次Code Review 时都担心所有的事情,那么任何代码都几乎不可能通过评审流程。要实现一个适合所有人的Code Review 流程,最好的方法是考虑以下问题。
  • 团队为什么要做审阅?当有一个明确的目的时,审查员的工作会更容易,代码作者也会从审查过程中减少讨厌的惊喜。
  • 团队成员要找的是什么?当有了目的,开发人员可以在审阅代码时创建一套更有针对性的东西来检查。
  • 谁来参与?谁来做评审,谁负责解决意见冲突,谁最终决定代码是否合格?
  • 团队何时进行复审,复审何时完成?审核可以在开发人员在代码工作的时候迭代进行,也可以在流程结束时进行。如果没有明确的指导,一个评审可能会一直进行下去,如果没有明确的指导,代码最终什么时候可以进行。
  • 团队在哪里做评审?Code Review 不需要特定的工具,所以审查可能就像作者在办公桌上带领同事看他们的代码一样简单。

一旦回答了这些问题,你的团队就应该能够创建一个运行良好的Code Review 流程。记住:Code Review 的目的应该是让代码投入生产,而不是证明开发人员有多聪明。

结论

Code Review 的错误模式可以通过建立一个明确的Code Review 流程来消除,或者至少是缓解。许多团队认为他们应该进行Code Review ,但他们没有明确的准则,为什么要进行Code Review 。

不同的团队需要不同类型的Code Review ,就像不同的应用程序有不同的业务和性能要求一样。第一步是弄清楚团队为什么需要审阅代码,然后团队就可以着手于:

  • 自动化的简易检查(例如,检查代码样式,识别常见的BUG,发现安全问题)。
  • 就审查的时间、审查的内容以及审查结束后由谁决定等问题制定明确的准则
  • 将Code Review 作为开发过程的一个关键工作内容

专注于为什么要进行Code Review ,将帮助团队创建Code Review 流程的最佳实践,这样就更容易避免Code Review 的错误模式。

原文:https://blogs.oracle.com/javamagazine/five-code-review-antipatterns

Code Review 常见的5个错误模式的更多相关文章

  1. 常见Code Review过程中发现的问题-续

    上一篇列举了一些比较常见的Code Review问题列表,文末有链接,可追溯查看.本篇为上篇的姊妹篇,继续列举一些上篇遗漏的或不易发现的问题清单,希望能整体性把一些常见的问题表述出来. 测试数据不具有 ...

  2. 我们是怎么做Code Review的

    前几天看了<Code Review 程序员的寄望与哀伤>,想到我们团队开展Code Review也有2年了,结果还算比较满意,有些经验应该可以和大家一起分享.探讨.我们为什么要推行Code ...

  3. Code Review 程序员的寄望与哀伤

    一个程序员,他写完了代码,在测试环境通过了测试,然后他把它发布到了线上生产环境,但很快就发现在生产环境上出了问题,有潜在的 bug. 事后分析,是生产环境的一些微妙差异,使得这种 bug 场景在线下测 ...

  4. <转>如何进行code review

    转自: http://pm.readthedocs.org/zh_CN/latest/codereview/howto.html 如何进行code review? code reivew是保障代码质量 ...

  5. Code Review Engine Learning

    相关学习资料 https://www.owasp.org/index.php/Code_review https://www.owasp.org/images/8/8e/OWASP_Code_Revi ...

  6. [充电]Code Review

    参考:http://blog.jobbole.com/83595/ http://www.kuqin.com/shuoit/20150319/345323.html 让 Code Review成为一种 ...

  7. 什么是Code Review(转)

    Code Review是一种通过复查代码提高代码质量的过程,在XP方法中占有极为重要的地位,也已经成为软件工程中一个不可缺少的环节.本文通过对Code Review的一些概念和经验的探讨,就如何进行C ...

  8. 什么是Code Review

    Code Review 是一种通过复查代码提高代码质量的过程,在XP方法中占有极为重要的地位,也已经成为软件工程中一个不可缺少的环节. 本文通过对Code Review的一些概念和经验的探讨,就如何进 ...

  9. 代码审查 (Google牛人谈Code Review)

    代码审查 (Google牛人谈Code Review) 在上一篇博客里我暗示自己将不在为Google工作. 我还没有决定好去哪儿-有几个非常不错的工作机会让我选择.鉴于这段时间内我不受雇于任何公司,我 ...

随机推荐

  1. JS Math&Date的方法 (上)

    数学对象&时间对象 本篇文章主要介绍Math 和 Date  的常用方法! 一 :Math & Date         Math 数学对象 - 处理数学计算和数学类          ...

  2. ubuntu搭建vulhub漏洞环境

    0x01 简介 Vulhub是一个面向大众的开源漏洞靶场,无需docker知识,简单执行两条命令即可编译.运行一个完整的漏洞靶场镜像.旨在让漏洞复现变得更加简单,让安全研究者更加专注于漏洞原理本身. ...

  3. ViewDragHelper的点击事件处理

    在上一篇ViewDragHelper的介绍后,已经完成了自定义控件SwipeLayout的滑动,这一篇,我们来处理它的点击事件.之前提到过,它有两个子view,最开始显示的是surfaceLayout ...

  4. python进入adb shell交互模式

    import subprocess #方法一:进入某个环境执行语句(adb shell),注意shell内部命令需要带\n,执行完后一定记得执行exit命令退出,否则会阻塞 obj = subproc ...

  5. DBeaver数据表的拷贝过程

    通过DBeaver工具链接数据库后,我们就可以通过菜单或者命令功能来实现我们想要的目的. (一)创建数据库 新建数据库,如下图所示:  ——> 在点击“确定”按钮后,可能会遇到失败,此时,我们可 ...

  6. Android-网页解析-gson的使用

    相对于较为传统的Json解析来说,google共享的开源Gson在解析速度和所使用的内存在有着明显的优势,虽然说阿里巴巴也提供了fastgson包,但是它跟Gson的处理速度大同小异,只是底层实现的原 ...

  7. PHP扩展Swoole的代码重载机制

    大家都知道Swoole的性能在PHP界还算不错,同样都是PHP为什么呢,我专门研究了下. 几个概念:   1) sapi:可以简单的理解为php引擎对外的一个统一接口,使得php可以和外部程序进行交互 ...

  8. Linux网络服务第一章Linux网络基础设置

    1.笔记 systenctl restart network:重启网卡网络服务 bash:刷新主机名称 netstat:查看网络状态 route -n:不做地址解析 mii-tool eno16777 ...

  9. HTML后台管理页面布局

    设计网页,让网页好看:网上找模板 搜 HTML模板 BootStrap 一.内容回顾: HTML 一大堆的标签:块级.行内 CSS position background text-align mar ...

  10. Leetcode PHP题解--D75 706. Design HashMap

    2019独角兽企业重金招聘Python工程师标准>>> D75 706. Design HashMap 题目链接 706. Design HashMap 题目分析 自行设计一个has ...