Code Review 是保证代码质量的重要手段之一,但许多研发团队中它常常由于各种原因并未得到真正的落地。为什么会这样呢?本文希望用一个非常简单的观点来理解这个现象,并据此给出一点优化的想法。

观点

我们的观点可以用一句话概括,那就是代码评审非常难同时满足高覆盖率、强约束力和低开销这三个条件。这三个条件分别有什么含义呢?

  • 高覆盖率,意味着评审需要覆盖项目中几乎所有的提交,而不是只评审新人的代码或者是批改暑假作业般的随机「抽查」。
  • 强约束力,意味着在保证评审本身质量的基础上,评审中指出的问题都需要得到切实的解决,否则不应合并代码或发布正式版本。
  • 低开销 (overhead),意味着评审不应占用过多宝贵的开发时间,更不应像某些会议那样提起来就让人皱眉头。

论证

满足上述三个条件的代码评审,应该是每一位对代码质量有追求的开发同学都不会排斥的。但为什么我们认为这样的评审可行性不高呢?简单地组合一下上述的条件,就不难发现矛盾了。

  • 同时满足高覆盖率强约束力的评审,时间是不可控的:为一些强调代码质量的开源项目贡献过 non-trivial 代码的同学,应该都知道即便是一个简单的 fix,其 PR 都可能因为实现手法和维护者的理解有偏差而长期保持在 Open 状态(俗称合不进去),更别说全新的特性与 API 了。
  • 同时满足高覆盖率低开销的评审,很容易流于形式:如果制度上约定必须对全部代码做评审,又不能耽误版本进度,那么这时候只要时间稍微一紧,评审就会变成日常回复 LGTM (Look Good To Me) 的走过场了。
  • 同时满足强约束力低开销的评审,很难覆盖到全部的代码库:一个版本中通常会有一些全新的特性。如果评审者并未参与这个新特性的开发,那么全量评审一个新特性的上千行代码,其难度跟打开一个没有读过的开源项目并马上指出其中的 bug 差不多。

折中

如果上述三者不可得兼,我们应该如何权衡呢?在目前的大环境下,多数软件项目快速迭代的性质与我们对「早点下班」的渴望,使得低开销这一条件通常很难被牺牲。那么在覆盖率约束力之间该如何取舍呢?让我们回到「代码评审有什么作用」这个话题上吧。我们知道代码评审可以:

  • 减少代码中的暗坑
  • 提高被评审者的代码质量
  • 让团队成员熟悉代码

如果评审本身就形同虚设,上面这些好处自然也只是空谈而已。因此,我们仍然很难放弃对约束力的要求。那么,如何改善这时覆盖率的问题呢?这里给出两点不成熟的想法供参考。

首先,来自 Google Subversion 团队的经验可以给我们一些启发:他们将代码评审与即时通信、会议、文档一起,视作团队中的沟通方式,而不是流程。这样,沟通方式之间就可以取长补短地提高团队效率。实际上,在评审全新特性时「读不过来」的问题,就可以通过设计阶段的文档来缓解:文档与评审同样是一对多的沟通,并且对文档中方案的讨论显然比直接讨论细节要更容易。一个需要 2 周时间左右开发出的全新特性,按照 问题定义 → 基本思路 → 实现概述 → 改进优化 的结构化方式编写的文档,其长度应该仅在千字左右,编写文档所需时间与开发时间应当不在一个量级,还能够节约在缺失文档时向其他同学当面沟通该特性的时间(当然,对那种顺手就能搞定的需求也要求文档化,就有些繁冗了)。

另外,代码评审的覆盖率问题,还可以通过一定的提交约定来优化。在笔者翻译的 conventional-commits 规范中,每一次提交都可以通过形如 fix / feat / chore / refactor 的不同类型来做区分,来达成细粒度的可读提交历史。那么,在评审的 Pull Request / Merge Request 粒度上,为什么不能同样地应用该规范呢?如果我们按照这种方式区分了 PR 类型,这里就有不少的想象空间:

  • 可以首先将评审的资源集中在 refactorperf 一类 PR 的评审上。
  • 对于 feat 类型存在大量新代码的 PR,只需其提供了确保团队成员理解的文档,那么就只需要保证方案设计可接受,做保证代码风格、命名、路径等隐式约定一致级别的评审即可。
  • 我们可以选择性忽略测试阶段可能数量众多的常规 fix 类 PR,但对版本发布后补充的 hotfix 类 PR,仍然需要评审。
  • 对不影响代码质量的 choredoc 类 PR 可以忽略评审。

总之,代码评审是一种沟通方式,希望它能够成为团队日常开发「文化」的一部分,而非束缚效率的死板流程。希望本文的想法对同样被评审困扰的同学有帮助 :)

P.S. 我们 base 厦门的前端工具(编辑器)团队缺人中,有意戳这里了解详情哈。

代码评审的不可能三角相关推荐

  1. 敏捷研发之代码评审与工具

    代码评审的主要内容 编码规范问题:命名不规范等 代码结构问题:重复代码.巨大大方法和类.分层不当.紧耦合 实现问题:错误验证.异常处理.事务划分.线程.性能.安全.实现过于复杂.代码可读性不佳.扩展性 ...

  2. 对不起,我的代码评审毁了一个程序员!

    技术使人膨胀?! 在过往的 coding 的生活中,你是否有过被技术前辈 diss 得找不着北的经历? 作者 | Philipp Ranzhin 译者 | 弯月 责编 | 屠敏 出品 | CSDN(I ...

  3. 11 个高效的同行代码评审最佳实践

    看到一篇同行评审的文章,感觉不错,特转载. 原文链接: http://www.ibm.com/developerworks/cn/rational/11-proven-practices-for-pe ...

  4. 【原创】项目管理杂谈(1):代码评审这点事,元芳你怎么看

    为什么80%的码农都做不了架构师?>>>    申明:因学识有限,某些见解和观点或有不妥,如有冒犯还请见谅.如需与作者联系,见文章底部个人签名处,乐于交流.Q群:210285832, ...

  5. 视频分享:编码与代码评审-质量与现实的最激烈冲突点(完整版)

    内容提要: 某次进度计划评审,QA发现缺少代码评审的环节,于是PM在所有编码任务之后增加了一个评审代码的任务,于是这个进度计划就通过评审了.代码评审不是走形式,领衔项目工作的你一定深受劣质代码的影响, ...

  6. 15个最佳的代码评审(Code Review)工具

    代码评审可以被看作是计算机源代码的测试,它的目的是查找和修复引入到开发阶段的应用程序的错误,提高软件的整体素质和开发者的技能.代码审查程序以各种形式,如结对编程,代码抽查等.在这个列表中,我们编制了1 ...

  7. 关于代码评审的微博讨论汇集

    编者按: 7月12日,weibo上 @自律自强 发表了一条微博:十几年来的软件项目经历告诉我,评审是最有效也是成本最低的质量保证和提升的手段,设计书和代码100%肉眼全覆盖绝对值得,而且还是迅速提高新 ...

  8. 远程开发 代码提示_VS Code 远程开发和代码评审实践

    很多年前的一天,我在 TypeScript 仓库下创建了一个 issue:微软打算拿 Monaco 来干嘛?接着第二天微软就发布了 VS Code.这个巧合我吹了五年还孜孜不倦. 因为已经用上了 Ty ...

  9. 评审恩仇录——IDE也能做代码评审?

    简介:云效Codeup推出了本地IDE插件端的评审,免除了黄药师来回华山的奔波之苦 现代科技公司的同事们平日一起交流开发规约和产品需求,肩上共同扛着业务发展和同行竞争的压力,这份还书贻剑的情谊如何能引 ...

最新文章

  1. pythondjango讲解_Django框架全面讲解
  2. gradient渐变IE兼容处理
  3. mysql数据结构优化,范式和反范式
  4. android加法服务类,iOS越来越像Android:苹果简单做加法远离精致
  5. 搞定ReentrantReadWriteLock 几道小小数学题就够了
  6. Windows下检测文件的MD5值
  7. NAT对语音业务的影响(网络控制方案…
  8. windows环境下面安装neo4j出错记录
  9. Android TextView 实现文字大小不同和文字颜色不同
  10. 从面试题中看Java的Reference(引用)
  11. 201204NEWS
  12. 【NodeJs-5天学习】第一天篇② —— 安装NodeJs环境以及VsCode开发工具
  13. 前端开发常用又好用的几个软件
  14. 计算机无法打开注册表,电脑无法打开注册表怎么办
  15. 用 WebGL 探索动画和交互技术(一个学习案例)
  16. Jasmine中describe和it
  17. mongodb 建立索引提示异常:WiredTigerIndex::insert: key too large to index, failing 1483
  18. Linux之scp命令的介绍以及命令行输入密码参数执行方法和常见问题解决
  19. Android11.0(R) MTK平台添加新分区
  20. 文本上划线_如何在Word中对文本进行上划线

热门文章

  1. boost::make_biconnected_planar用法的测试程序
  2. boost::geometry::enrich_intersection_points用法的测试程序
  3. GDCM:dicom文件固定方向的测试程序
  4. Boost:bind绑定查找问题的测试程序
  5. ITK:计算两个图像之间的均方度量值
  6. ITK:创建一个向量
  7. DCMTK:演示状态查看器-网络接收组件(存储SCP)
  8. C语言用‘%20‘替换字符串中的所有空格的算法(附完整源码)
  9. OpenGL simpletexture简单的纹理的实例
  10. C++ Opengl 透明纹理源码