Code Review最佳实践

Code Review最佳实践

Code Review

  • 我一直认为Code Review(代码审查)是软件开发中的最佳实践之一,可以有效提高整体代码质量,及时发现代码中可能存在的问题。包括像Google、微软这些公司,Code Review都是基本要求,代码合并之前必须要有人审查通过才行。
  • 然而对于我观察到的大部分软件开发团队来说,认真做Code Review的很少,有的流于形式,有的可能根本就没有Code Review的环节,代码质量只依赖于事后的测试。也有些团队想做好代码审查,但不知道怎么做比较好。
  • 网上关于如何做Code Review的文章已经有很多了,这里我结合自己的一些经验,也总结整理了一下Code Review的最佳实践,希望能对大家做好Code Review有所帮助。

Code Review有什么好处?

  • 很多团队或个人不做Code Review,根源还是不觉得这是一件有意义的事情,不觉得有什么好处。这个问题要从几个角度来看。

  • 首先是团队知识共享的角度

  • 一个开发团队中,水平有高有低,每个人侧重的领域也有不同。怎么让高水平的帮助新人成长?怎么让大家都对自己侧重领域之外的知识保持了解?怎么能有人离职后其他人能快速接手?这些都是团队管理者关心的问题。

  • 而代码审查,就是一个很好的知识共享的方式。通过代码审查,高手可直接指出新手代码中的问题,新手可以马上从高手的反馈中学习到好的实践,得到更快的成长;通过代码审查,前端也可以去学习后端的代码,做功能模块A的可以去了解功能模块B的。

  • 可能有些高手觉得给新手代码审查浪费时间,自己也没收获。其实不然,新人成长了,就可以更多的帮高手分担繁重的任务;代码审查中花时间,就少一些帮新人填坑擦屁股的时间;良好的沟通能力、发现问题的能力、帮助其他人成长,都是技术转管理或技术上更上一层楼必不可少的能力,而通过代码审查可以有效的去练习这些方面的能力。

  • 然后是代码质量的角度

  • 现实中的项目总是人手缺进度紧,所以被压缩的往往就是自动化测试和代码审查,结果影响代码质量,欠下技术债务,最后还是要加倍偿还。

  • 也有人寄希望于开发后的人工测试,然而对于代码质量来说,很多问题通过测试是测试不出来的,只能通过代码审查。比如说代码的可读性可维护性,比如代码的结构,比如一些特定条件才触发的死循环、逻辑算法错误,还有一些安全上的漏洞也更容易通过代码审查发现和预防。

  • 也有人觉得自己水平高就不需要代码审查了。对于高手来说,让别人审查自己的代码,可以让其他人学习到好的实践;在让其他人审查的同时,在给别人说明自己代码的时候,也等于自己对自己的代码进行了一次审查。这其实就跟我们上学时做数学题一样,真正能拿高分的往往是那些做完后还会认真检查的。

  • 还有团队规范的角度

  • 每个团队都有自己的代码规范,有自己的基于架构设计的开发规范,然而时间一长,就会发现代码中出现很多不遵守代码规范的情况,有很多绕过架构设计的代码。比如难以理解和不规范的命名,比如三层架构里面UI层绕过业务逻辑层直接调用数据访问层代码。

  • 如果这些违反规范的代码被纠正的晚了,后面再要修改就成本很高了,而且团队的规范也会慢慢的形同虚设。

    通过代码审查,就可以及时的去发现和纠正这些问题,保证团队规范的执行。

    关于代码审查的好处,还有很多,也不一一列举。还是希望能认识到Code Review和写自动化测试一样,都是属于磨刀不误砍柴工的工作,在上面投入一点点时间,未来会收获代码质量,会节约整体的开发时间。

该怎么做?

  • 现在很多人都已经有意识到Code Review的重要性了,只是苦于不知道如何去实践,不知道怎么样算是好的Code Review实践。

把Code Review作为开发流程的必选项而不是可选项

  • 在很早以前,我就尝试过将代码审查作为代码流程的一部分,但只是一个可选项,没有Code Review也可以把代码合并到master。这样的结果就是想起来才会去做Code Review,去检查的时候已经有了太多的代码变更,审查起来非常困难,另外就算审查出问题,也很难得以修改。
  • 我们现在对代码的审查则是作为开发流程的一个必选项,每次开发新功能或者修复Bug,开一个新的分支,分支要合并到master有两个必要条件:
  • 所有的自动化测试通过
  • 有至少一个人Code Review通过,如果是新手的PR,还必须有资深程序员Code Review通过
  • img
  • 这样把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工具,典型的像Github、Gitlab、微软的Azure DevOps,尤其是像Gitlab,还可以自己在本地搭建环境,根据自己的需要灵活配置。

配合什么样的开发流程比较好?

  • 像Github Flow这样基于分支开发的流程是特别适合搭配Code Review的。其实不管什么样的开发流程,关键点在于代码合并到master(主干)之前,要先做Code Review。

真遇到紧急情况,来不及代码审查怎么办?

  • 虽然原则上,必须要Code Review才能合并,但有时候确实会存在一些紧急情况,比如说线上故障补丁,而又没有其他人在线,那么这种情况下,最好是在任务管理系统中,创建一个Ticket,用来后续跟踪,确保后续补上Code Review,并对Code Review结果有后续的代码更新。

先设计再编码

  • 有些新人发现自己的代码提交PR(Pull Request)后,会收到一堆的Code Review意见,必须要做大量的改动。这多半是因为在开始做之前,没有做好设计,做出来后才发现问题很多。
  • 建议在做一个新功能之前,写一个简单的设计文档,表达清楚自己的设计思路,找资深的先帮你做一下设计的审查,发现设计上的问题。设计上没问题了,再着手开发,那么到Review的时候,相对问题就会少很多。

代码在提交CODE REVIEW之前,作者要自己先REVIEW和测试一遍

  • 我在做代码审查的时候,有时候会发现一些非常明显的问题,有些甚至自己都没有测试过,就等着别人Code Review和测试帮助发现问题。这种依赖心理无论是对自己还是对团队都是很不负责任的。
  • 一个好的开发人员,代码在提交Code Review之前,肯定是要自己先Review一遍,把该写的自动化测试代码写上,自己把基本的测试用例跑一遍的。
  • 我对于团队提交的PR,有个要求就是要在PR的描述中增加截图或者录屏,就是为了通过截图或者录屏,确保提交PR的人自己是先测试过的。这也是一个有效的辅助手段。

PR要小

  • 在做Code Review的时候,如果有大量的文件修改,那么Review起来是很困难的,但如果PR比较小,相对就比较容易Review,也容易发现代码中可能存在的问题。
  • 所以在提交PR时,PR要小,如果是比较大的改动,那么最好分批提交,以减轻审查者的压力。
  • 在这里插入图片描述

对评论进行分级

  • 在做Code Review时,需要针对审查出有问题的代码行添加评论,如果只是评论,有时候对于被审查者比较难甄别评论所代表的含义,是不是必须要修改。

  • 建议可以对Review的评论进行分级,不同级别的结果可以打上不同的Tag,比如说:

    • [optional]:在评论前面加上一个[optional]标记,表示这个代码行的问题可改可不改

    • [question]:在评论前面加上一个[question]标记,表示对这个代码行不理解,有问题需要问,被审查者需要针对问题进行回复澄清

  • 类似这样的分级可以帮助被审查者直观了解Review结果,提高Review效率。

评论要友好,避免负面词汇;有说不清楚的问题当面沟通

  • 虽然评论是主要的Code Review沟通方式,但也不要过于依赖,有时候面对面的沟通效率更高,也容易消除误解。
  • 另外文明用语,不要用一些负面的词汇。

总结

  • Code Review是一种非常好的开发实践,如果你还没开始,不妨逐步实践起来;如果已经做了效果不好,不妨对照一下,看有没有把Code Review作为开发流程的必选项而不是可选项?有没有把Code Review变成一种开发文化而不仅仅是一种制度?

-----------------------------------------------------------------------------------

offer突击训练营简介:

1:针对不知道怎么面试,面试没有信心的小伙伴,我们会给你一个offer保障。

2:我们会监督你15-20天内把面试体系技术点掌握至少7成,这样足够你去找到满意的工作了。

3:我们是面向面试学习指导,不会带你们去写代码,会把项目真实开发的迭代过程和技术细节如何实现业务功能都详细教清楚,你能在面试中流畅表达清楚就行了,项目经验你不用担心(技术老师提供的真实项目经验肯定拿的出手),自己学和别人带着系统学,效率完全不一样。

详情请点击这里:offer突击训练营,给你一个offer的保障,求职跳槽的看过来!

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.mzph.cn/news/136567.shtml

如若内容造成侵权/违法违规/事实不符,请联系多彩编程网进行投诉反馈email:809451989@qq.com,一经查实,立即删除!

相关文章

【数据结构】树与二叉树(七):二叉树的遍历

文章目录 5.1 树的基本概念5.1.1 树的定义5.1.2 森林的定义5.1.3 树的术语5.1.4 树的表示 5.2 二叉树5.2.1 二叉树1. 定义2. 特点3. 性质引理5.1:二叉树中层数为i的结点至多有 2 i 2^i 2i个,其中 i ≥ 0 i \geq 0 i≥0。引理5.2:高度为k的二叉…

代挂单页网址发布页+加盟代理+APP下载页源码

代挂单页加盟代理网址发布页app下载页HTML单页版本,自行修改源码内文字。自行修改联系方式、登录地址!上传即可使用。源码我已全部打包好,直接上传本站提供的源码,无后台,直接访问即可! 源码下载&#xff…

EF Core 数据库映射成实体类

首先在 NuGet 包管理器中安装三个包 Microsoft.EntityFrameworkCore.SqlServer 是一个用于与 SQL Server 数据库进行交互的实体框架核心包。这个包提供了方便的方法和工具,用于在 .NET Core 应用程序中操作 SQL Server 数据库。 Microsoft.EntityFrameworkCore.Too…

fmx windows 下 制作无边框窗口最小化最大化并鼠标可拖移窗口

1,最顶端 放一个rectangle 置顶 ,此区域后面实现鼠标拖动 移动窗口,可在上面放置最大,最小,关闭按钮 2,窗口边框模式 设置 none 3,rectangel mousemove事件 uses Winapi.Windows,Winapi.Messages,FMX.Platform.Winprocedure TfrmMain.Rectangle1MouseMove(Sender: TObje…

[直播自学]-[汇川easy320]搞起来(3)看文档安装软件 查找设备

2023.11.09 20:04 按照文档 解压压缩包得到: 打开 里面有一条值得注意: 想把软件安装到C盘,但是C盘没什么空间了,把C盘清理清理。 20:35 安装很快完成,然后阅读 由于PLC是新的&#xff0c…

Postgresql数据类型-布尔类型

前面介绍了PostgreSQL支持的数字类型、字符类型、时间日期类型,这些数据类型是关系型数据库的常规数据类型,此外PostgreSQL还支持很多非常规数据类型,比如布尔类型、网络地址类型、数组类型、范围类型、json/jsonb类型等,从这一节…

Bean作用域

从笔者之前的博客,我们可以看出 Spring 是⽤来读取和存储 Bean,因此在 Spring 中 Bean 是最核⼼的操作 资源,所以接下来我们深⼊学习⼀下 Bean 对象:Bean作用域! 限定程序中变量的可用范围叫做作用域!或者…

scss 实用教程

变量 $ 定义变量 $link-color: blue;变量名可以与css中的属性名和选择器名称相同 使用变量 a {color: $link_color; }$highlight-border: 1px solid $link_color;中划线和下划线相互兼容,即中划线声明的变量可以使用下划线的方式引用,反之亦然。 $li…

5分钟Python安装实战(MAC版本)

最近在学习Chatgpt接口,官方提供三种方式调用Chatgpt接口,分别是curl、python、node.js:具体介绍我放在下方图片 因为熟悉Python,所以我选择了python这种方式,顺便记录下安装过程,整体并不复杂,…

npm 下载包失败解决方案

1.【问题描述】使用 npm 下载vue项目依赖包时失败,版本不一致。 【解决方法】使用 npm install --force npm install --force 是一个命令行指令,用于在 Node.js 环境中使用 npm(Node Package Manager)安装包或模块。–force 参数表…

单例模式 rust和java的实现

文章目录 单例模式介绍应用实例:优点使用场景 架构图JAVA 实现单例模式的几种实现方式 rust实现 rust代码仓库 单例模式 单例模式(Singleton Pattern)是最简单的设计模式之一。这种类型的设计模式属于创建型模式,它提供了一种创建…

【Git企业开发】第六节.配置 Git和标签管理

文章目录 前言一、配置 Git 1.1 忽略特殊文件 1.2 给命令配置别名二、标签管理 2.1 理解标签 2.2 创建标签 2.3 操作标签 总结 前言 一、配置 Git 1.1 忽略特殊文件 在日常开发中,我们有些文件不想或者不应该提交到远端,…

2022年06月 Python(四级)真题解析#中国电子学会#全国青少年软件编程等级考试

Python等级考试(1~6级)全部真题・点这里 一、单选题(共25题,每题2分,共50分) 第1题 有如下Python程序,包含lambda函数,运行该程序后,输出的结果是?( ) g = lambda x,y:x*y print(g(2,3)

设计模式之保护性暂停

文章目录 1. 定义2. 实现保护性暂停模式3. Join原理4. 保护性暂停模式的扩展 1. 定义 即Guarded Suspension,用在一个线程等待另一个线程的执行结果。 有一个结果需要从一个线程传递给另一个线程,让他们关联到同一个GuarderObject(这就是保…

SPASS-交叉表分析

导入数据 修改变量测量类型 分析->描述统计->交叉表 表中显示行、列变量通过卡方检验给出的独立性检验结果。共使用了三种检验方法。上表各种检验方法显著水平sig.都远远小于0.05,所以有理由拒绝实验准备与评价结果是独立的假设,即认为实验准备这个评价指标是…

【Git系列】Github指令搜索

💝💝💝欢迎来到我的博客,很高兴能够在这里和您见面!希望您在这里可以感受到一份轻松愉快的氛围,不仅可以获得有趣的内容和知识,也可以畅所欲言、分享您的想法和见解。 推荐:kwan 的首页,持续学…

深度学习之基于Python+OpenCV(DNN)性别和年龄识别系统

欢迎大家点赞、收藏、关注、评论啦 ,由于篇幅有限,只展示了部分核心代码。 文章目录 一项目简介 二、功能三、系统四. 总结 一项目简介 基于Python和OpenCV的深度学习性别和年龄识别系统是一种利用深度学习模型来自动识别人脸照片中的性别和年龄的技术。…

论文速览 | TRS 2023: 使用合成微多普勒频谱进行城市鸟类和无人机分类

注1:本文系“最新论文速览”系列之一,致力于简洁清晰地介绍、解读最新的顶会/顶刊论文 论文速览 | TRS 2023: Urban Bird-Drone Classification with Synthetic Micro-Doppler Spectrograms 原始论文:D. White, M. Jahangir, C. J. Baker and M. Antoniou, “Urban Bird-Drone…

SAP ABAP基础语法-Excel上传(十)

EXCEL BDS模板上传及赋值 上传模板事务代码:OAER l 功能代码:向EXCEL模板中写入数据示例代码如下 REPORT ZEXCEL_DOI. “doi type pools TYPE-POOLS: soi. *SAP Desktop Office Integration Interfaces DATA: container TYPE REF TO cl_gui_custom_c…

React向组件内部动态传入带内容的结构--props

children props&#xff1a;通过组件标签体传入结构 <A><B>xxx</B> </A> {this.props.children}render props&#xff1a;通过组件标签属性传入结构&#xff0c;一般用render函数属性 <A render{data> <C data{data}></C>}></…