Loading [MathJax]/jax/input/TeX/config.js
前往小程序,Get更优阅读体验!
立即前往
首页
学习
活动
专区
圈层
工具
发布
首页
学习
活动
专区
圈层
工具
MCP广场
社区首页 >专栏 >Code Review最佳实践

Code Review最佳实践

作者头像
进击的大葱
发布于 2022-08-22 06:18:59
发布于 2022-08-22 06:18:59
9310
举报
文章被收录于专栏:前端急先锋前端急先锋

因为最近在工作上参与制定了团队的一些Code Review(CR)的规范,所以想在这里给大家分享一下我们积累的一些CR最佳实践。本篇文章会包括下面这些内容:

•为什么需要Code Review

•什么时候做Code Review

•Committer需要注意什么

•Code Reviewer需要看哪方面的内容

为什么需要Code Review

对于参与人数大于或者等于两个的项目来说,CR是一项必不可少的活动。在我看来它有下面这些好处:

可以提高committer对于自己代码的要求

按照我以往的经验来说,有些人的代码在被review和不会被review的时候风格是完全不一样的。如果一个人写的代码不用别人看,永远都是直接推到或者直接合入主分支的话,这个人写代码的时候就不会有什么顾忌,自己想怎么写就怎么写,反正也不会有人看。可是当他的代码需要被同伴review时,他的心态就完全不一样了,这个时候他会想办法精简代码,去掉一些硬编码的逻辑从而追求一些最佳实践,而且各种TODOFIXME也会写得一清二楚。因为他如果不怎么做的话,作为一个及格的code reviewer,我们是肯定不会将他的代码合入主分支的。长期如此的话,committer的代码水平也会逐渐得到提高的。

组内知识分享

俗话说的好:你有一个苹果,我有一个苹果,我们交换一下,一个人还是只有一个苹果;你有一个思想,我有一个思想,我们交换一下,一人就有了两个思想。这句话同样适用于我们进行软件开发。作为一个程序员,我们在面对同一个问题的时候,可能会有不同的解决方法。如果大家没有交流的话,每个人可能永远都只知道一种解决方法,大家也就没有进步可言。那么程序员之间如何互相学习呢?最简单的办法就是看别人的源代码,而CR就是最好的阅读别人源代码的过程。因为当我们在帮committer进行review的时候,他提交的代码只专注于解决一个问题,这样代码量就不会很大,我们可以更加清晰地学习到他是如何解决某一个问题的。如果committer恰好用了一个很巧妙的我们之前不知道的办法来解决问题的话,我们就可以学习到新的知识了。

保持项目代码风格的一致性

同一个项目里面不同的程序员由于背景不一样(可能来源于不同的项目,来源于不同的公司),他们解决问题的方法和思路就不一样。作为一个前端程序员我见过在同一个代码仓库里面同时使用了redux-sagaredux-thunk作为异步中间件的。如果作为code reviewer我们不对committer的代码进行约束的话,项目的代码风格就会多极分化,这无疑会增加项目的维护成本以及后面新加入开发者的学习成本

提前发现代码的问题

一些经验比较少的开发者在写代码的时候可能考虑问题不够全面,导致一些边缘情况(edge case)没有考虑到,这时候如果code reviewer是一个工作经验比较多的同学的话,就可以帮committer提前发现问题,这样就可以避免在产品上线后再浪费时间去定位问题了。值得注意的是,就算code reviewer不是一个很资深的开发,他作为代码的局外人往往也可以考虑到当事人(committer)在写代码时考虑不到的情况的。

什么时候进行Code Review

CR一定要发生在各种CI自动化检查例如单元测试lint检查等通过之后和代码正式合入主分支之前

这里涉及到的一个问题是如果我们开发的功能涉及的改动很多的话,是等我们都开发完后再一起给reviewer看呢还是拆分成一个个小的MR(Merge Request)给reviewer看呢?我个人偏向于后者。因为如果你提的代码很多的话,code reviewer需要花很多时间去阅读你的代码,理解各个模块之间是如何协作的,而且给你提问题后,你可能需要改动很多的地方,这就导致整个CR周期变得很长,这些其实都会打击code reviewer给你挑毛病的积极性,这种情况下,一些没有耐心的code reviewer可能就给你一个简单的LGTM然后就将你的代码合入主分支了,这样的CR是毫无意义的。因此更好的做法是在开发大功能时候将代码拆分成一个个小的模块,每完成一个小的模块就合入主分支,直到所有的功能都合并入主分支为止。可是如果开发者不想将自己未完成的功能模块合入主分支怎么办呢?这个时候可以使用一种叫做stacked CR的模式:首先从主分支切出一个feature/big-feature的分支,你后面在开发这个big-feature的时候,都是从这个feature/big-feature分支切出各种功能的小分支,例如feature/big-feature-sub-feature1feature/big-feature-sub-feature2等。当你在小分支上开发完后就可以提MR将代码合入feature/big-feature分支上。这样由于每个MR都很小,所以code reviewer就可以认真仔细地给你挑毛病了。最后等你把所有的功能都合并到feature/big-feature上后,就可以提一个MR将这个分支的内容合入主分支了。这个时候虽然改动还是很多,不过由于code reviewer已经在之前的阶段看过了你所有的更改,这个时候他要看的东西其实就不多了,对他进行CR也不会有很大的阻碍。

Committer需要注意什么

作为代码的提交者,如果我们希望我们提交的代码可以被code reviewer认真对待并且得到有用的反馈的话,需要注意下面这些方面:

限制每个commit的改动大小和范围

我们CR的时候,最烦的其实就是看到其他人提交了一大堆改动,因为这样我们就需要花很多时间去理解他的逻辑,这也是很多项目很难进行有效CR的主要原因,那就是从开始提交代码的时候就已经错了。作为committer,我们在提交代码的时候需要将改动控制在一个合理的范围,我个人的一个偏好是将改动的文件数控制在5个文件以内,将改动的代码行数控制在150行以内,这样的话reviewer就不需要花费太多时间来帮我们review代码,并且也乐于给我们提供更改意见。除了改动大小的限制,我们同时也要注意commit的范围,确保每一个commit都只做一件事。举个例子: 作为一个前端程序员,你在实现一个导航组件的时候,不要顺带修复一两个bug,或者更改一些配置信息,你应该将你这个commit集中在导航组件的实现上面。换句话来说就是:你要保证你的每一个commit只完成某一个功能或者修复某一个bug,不要将它们"捆绑销售"

Commit信息要有意义

很多开发者在commit的时候都不会认真写commit message,特别是在外企要求你用英文写的时候:)。工作多年,我见过一些很懒的开发,他们所有的新增功能都叫feature或者是add a new feature,所有修复的bug都叫bugfix或者fix some bug。这些commit message是没有什么意义的,因为它们没有告诉code reviewer这些代码到底开发了什么新功能或者修复了哪个bug。要编写一个好的commit message,首先得给它固定一个格式。现在业界比较推崇和出名的commit message格式是conventional commit[1], conventional commit的主要作用是将我们所有提交进行分类,例如feat代表feature, fix代表bugfix等等。当我们的commit分好类后,除了便于阅读,还有一个好处就是一些自动化生成changelog的工具可以很方便地根据我们某个版本内的所有commit的信息生成这个版本的changelog。除了所有commit message都要遵循某一个固定的格式外,我们还需要在commit message里面写明白我们的代码到底实现了什么功能或者修复了什么bug。如果你在某个commit里面实现了一个用户注册的功能,你的commit信息可以写成feat: implement user signup logic而不是feat: add new feature,如果你修复了登录按钮不可以点击的bug,你的commit信息可以写成fix: login button can not be clicked而不是fix: fix some bug

Code Review需要看什么东西

那么作为一名合格的code reviewer,我们在帮项目成员进行CR的时候需要看哪些内容呢?根据我个人的经验,我总结了下面这些方面的内容:

正确实现了功能或者修复了bug

作为code reviewer,我们首先要保证的是,committer提交的MR正确地实现了某个功能或者确实修复了某个bug。在我们实际开发的过程中,由于信息传递的不一致或者是开发者理解存在偏差,committer在提交代码的时候可能没有实现完所有的功能或者没有彻底修复QA发现的bug,这个时候我们就可以在做CR的时候指出来防止到QA测试的时候甚至是上线的时候再发现问题。不过要注意的是,这不代表committer不需要自测,相反committer自己在提交代码的时候需要尽最大努力保证自己的代码功能上是没有问题的。

确保编码风格一致

这可能是CR最基本也是最重要的一个目的了。作为一个前端程序员虽然我们可能有一些诸如eslint的工具去帮助我们确保代码格式一致,例如statement后面要不要带分号,缩进是4个空格或者两个空格等。可是由于风格不只是格式,有很多编码风格的问题是不能用eslint这种自动化工具进行约束,而是要靠code reviewer在CR阶段指出来。因此作为code reviewer,我们需要在CR的时候确保合入主分支的代码风格基本保持一致,避免不一样的编码风格降低项目代码的可读性和可维护性

避免非必要的复杂逻辑设计

因为在同一个项目里面每个人的水平和工作经验都不一样,所以面对同样的问题,有的开发者会用非常优雅和简洁的解决方案去实现,而有的开发者受制于自身的能力,会想出一种非常复杂的解决方案。无必要的复杂的代码逻辑会降低代码的可读性、可维护性和鲁棒性。作为code reviewer,当我们看到过度复杂的代码时一定要指出来,然后尝试和committer一起想出一种更加简单的解决方案(参考开源方案等)

避免硬编码

硬编码的逻辑和值会降低代码的可读性和可维护性,并且会增加bug出现的概率。因此作为code reviewer,当我们看到一些硬编码的逻辑或者一些诸如magic number等hard-coded values时,可以叫committer将逻辑设计得尽量通用或者将硬编码的值定义为常量值

提高代码复用率

当我们项目有很多人参与的时候,开发者在实现某个功能时候可能会重复造一些前人造过的轮子,在前端项目里面可以理解成一些公共组件公共hook或者是帮助方法等。重复的代码一旦合入主分支会降低代码的可维护性并且也会容易引发bug(想一下如果某个需求变了,你要改多个地方就知道了)。因此作为code reviewer,我们在CR阶段的一个重要任务就是识别出代码的重复逻辑。简单来说,重复逻辑包括三种。第一种是committer提交CR的代码和代码仓库现有的代码逻辑发生了重复,这个时候提醒开发者复用之前的逻辑就可以了。第二种是开发者提交的代码里面有重复的逻辑,这个时候需要开发者通过抽取公共函数或者组件的方法来提高自己代码的复用度和内聚度。第三种情况是开发者提交的代码和现有的逻辑有部分重叠,可是现有逻辑不能直接被复用,这种情况需要code reviewer和开发者进行合作,想办法对旧逻辑进行改造从而满足新的需求。举个例子,假如我们现有代码仓库已经实现了用来展示错误消息的Notification组件,committer在新的需求里面提交了一个全新的用于展示警告的Notification组件,这个组件的样式基本和之前的一致只有一些细小的文字颜色的区别,重新写一个的话就意味着当UI设计师更改Notification的样式时,我们需要更改两个地方,这是完全没必要并且低效的。这个时候作为code reviewer,我们要让committer修改之前Notification组件的逻辑让其变得更加通用,然后在新的需求中复用这个组件。当然更改之前组件的逻辑和我们新的需求需要放在两个不同的commit里面,因为我们要限制每个commit的改动大小和范围。

写上必要的代码注释

好的代码注释是用来告诉别人你为什么写这样的代码,而不是告诉别人你的代码做了什么。如果你需要一步步写明白你的代码做了什么的话,首先已经说明你的代码不及格了,因为好的代码风格是会让人通俗易懂的。相反当我们为了克服后端接口的一些bug,或者绕开框架的一些问题而写的一些奇怪逻辑时,我们才需要通过代码注释来告诉别人你写这些代码的目的是什么。除了这些,你也可以使用一些诸如FIXMETODO的关键词来告诉别人某段代码还有可以提高的空间或者某个功能还没有完全实现。这里值得一说的是,虽然很多开发会用FIXMETODO等关键词,可是他们喜欢干巴巴地放这么一个关键词在注释里面而没告诉其他开发或者未来的自己什么需要做或者什么需要被提高,这种代码注释同样是没有什么用的。因此作为code reviewer我们不但需要确保committer写了该写的注释,同样也要确保他写的注释是有意义的

带上必要的自动化测试

CR还有一个重要的作用就是确保committer在提交代码的时候带上必要的自动化测试,例如单元测试和e2e测试等。作为一个前端开发,其实很多人是不写单元测试的,其中一个比较重要的原因是不同于后端接口,前端需要变化太快,刚写完的测试可能下个版本就不能用了,或者是测试用例需要写太多,写测试的时间比写代码的时间还要多。但是我们又不能一点测试都不写,因此测试还是有很多作用的,例如可以帮助我们提前发现问题,好的单元测试还可以当做组件或者函数的文档使用,同时测试也可以帮我们更加高效地进行代码的重构。那么什么代码一定要写测试呢?在我看来,所有的公共逻辑,包括公共组件,公共hook和函数都应该写测试,这是因为公共的东西就意味着使用的人多,如果其中一个人随意改动的话,很容易会造成其他人的逻辑出现问题,因此我们需要通过单元测试来确保我们对于公共逻辑的更改不会引发潜在的bug。另外一个需要写测试的地方是复杂的逻辑。复杂的逻辑写测试的目的是让我们可以尽量模拟不同的输入情况,以提高我们代码的鲁棒性。因此作为一个code reviewer我们在进行CR的时候既要确保committer写了必要的自动化测试,同时也满足一定的测试覆盖率。

总结

在本文中我介绍了一些CR最佳实践的内容,其实按照我个人的经验来说,团队规模小需求不紧的时候,按照上面的要求进行CR还不是一件比较难的事。相反当项目参与的人数变多了,而且版本迭代速度加快后,很多团队开始放松了对CR的要求,可是实际上往往是这个时候我们才更加需要严格的CR来保证代码风格一致以及避免快速迭代导致的代码维护性下降等问题。最后想说得一句话是:做好code review很难很麻烦,不过好的code review实践对项目或者个人的发展都有巨大的作用

References

[1] conventional commit: https://www.conventionalcommits.org/en/v1.0.0/

本文参与 腾讯云自媒体同步曝光计划,分享自微信公众号。
原始发表:2022-03-21,如有侵权请联系 cloudcommunity@tencent.com 删除

本文分享自 进击的大葱 微信公众号,前往查看

如有侵权,请联系 cloudcommunity@tencent.com 删除。

本文参与 腾讯云自媒体同步曝光计划  ,欢迎热爱写作的你一起参与!

评论
登录后参与评论
暂无评论
推荐阅读
编辑精选文章
换一批
我们是怎么做Code Review的
前几天看了《Code Review 程序员的寄望与哀伤》,想到我们团队开展Code Review也有2年了,结果还算比较满意,有些经验应该可以和大家一起分享、探讨。 我们为什么要推行Code Review呢?我们当时面临着代码混乱、Bug频出的状况。 当时我觉得要有所改变,希望能提高产品的代码质量,改善开发团队面临的困境。并且我个人在开发上有很多经验,也希望这些知识能够在团队内传播。 各种考虑后,我们最后认为推行Code Review能改善或解决我们面临的很多问题。 这篇文章的目的不是告诉大家怎么在一个团
李海彬
2018/03/23
1.8K0
如何有效地进行代码 Review?
| 导语  研发都知道代码 Review 的重要性,在腾讯代码 Review 也越来越受大家重视,作为腾讯专有云平台研发的一员,我参与了大量的代码 Review,明显地感受到有效的代码 Review 不但能提高代码的质量,更能促进团队沟通协作,建立更高的工程质量标准,无论对个人还是团队都有着重要的价值。本文就为什么要做代码 Review 以及如何有效地做代码 Review 分享一下个人的看法。 1 为什么要做代码 Review 为什么要代码 Review,相信每个人心中都有比较一致的答案,Google
腾讯大讲堂
2020/09/25
5800
Code Review在TDSQL-C 的应用实践
结合下面这个例子,我们来谈谈为什么要重视code review。假设你作为新人刚入职,领导分配了一个需求,于是接下来做了下面这些事:
腾讯 架构师
2021/07/12
7030
Code Review在TDSQL-C 的应用实践
MEP | Code Review 建议
一、目标和原则二、开发者三、评审者四、实用性建议1. 对事不对人2. 每个 Review 至少给一条正面评价3. 使用统一的代码风格规范4. 全员参加 Code Review,并设定各部分负责人5. 每次 Code Review 的量不宜太多6. 在写新代码之前,先 Review 掉需要评审的代码7. 如果你有更好的方案,尽管提出来8. 不要在 Review 中讨论需求,Review 就是 Review9. 不要试图一次就能改善所有的问题10. 交叉 Review五、小项目团队内部采用轮换 Review 的方式六、推荐几款代码检查工具静态代码风格检测Bug 扫描参考
双鬼带单
2021/09/09
4220
MEP | Code Review 建议
如何在团队中做好Code Review
想要做好Code Review,必须让参与的工程师充分认识到Code Review的好处
KenTalk
2019/12/23
1.4K0
如何在团队中做好Code Review
直播回顾 | DevOps 代码质量实战:代码规范与 Git Flow
关注腾讯云大学,了解行业最新技术动态 戳【阅读原文】观看完整课程回顾 讲 师 介 绍  连续创业者、DIY/Linux 玩家、知乎小 V,曾在创新工场、百度担任后端开发。十余年一线研发和带队经验,经历了 ToB、ToC、O2O、国内、出海各种项目,见证了云计算时代的诞生,擅长研发最佳实践:Code Review、DevOps、Git Workflow、敏捷开发、架构、极客办公硬件。  背景 随着 ToB(企业服务)的兴起和 ToC(消费互联网)产品进入成熟期,线上故障带来的损失越来越大,代码质量越
腾讯产业互联网学堂1
2023/05/29
2250
直播回顾 | DevOps 代码质量实战:代码规范与 Git Flow
高效团队的gitlab flow最佳实践
当前git是大部分开发团队的首选版本管理工具,一个好的流程规范可以让大家有效地合作,像流水线一样有条不紊地进行团队协作。
JadePeng
2021/02/04
4.3K0
高效团队的gitlab flow最佳实践
【译】Google 官方文章——如何去做coder review
cr(Code review)主要目的在于确保Google 的代码库代码质量越来越好。而所有相关的工具与流程皆是因应这个目的而生。为达到此目的,势必需要做出一连串的权衡与取舍
lhyt
2019/09/18
5970
【译】Google 官方文章——如何去做coder review
漫谈 React 组件库开发(二):组件库最佳实践
一个系统拥有大量的业务场景和业务代码,相似的页面和代码层出不穷,如何管理和抽象这些相似的代码和模块,这肯定是诸多团队都会遇到的问题。不断的拷代码?还是抽象成 UI 组件或业务组件?显然后者更高效。
有赞coder
2020/08/25
1.7K0
漫谈 React 组件库开发(二):组件库最佳实践
有赞零售移动CI/CD实践
随着有赞零售业务的蓬勃发展,为了尽早交付有价值的应用满足客户需求,我们采用了敏捷开发的模式,快速拥抱变化的同时保持竞争优势。从 2019 年起,零售客户端的发版周期更改为每周一次,这对移动端的持续集成与交付提出更高的要求。如何根据现有的团队规模,在有限的资源下,快速搭建稳定可靠的持续集成与交付系统,我们有了自己的实践与思考。
有赞coder
2020/09/01
1.3K0
有赞零售移动CI/CD实践
2018-10-31 Code Review 在丁香医生前端团队的实践
时间过得很快,转眼间 Code Review 机制在丁香医生前端团队已经运作一年多了。今年4月初时,将团队在 Code Review 方面的一些经验在丁香园前端团队进行了分享,各个业务线的前端同学们逐步开始尝试 Code Review 机制,目前也有了一定的收获。是时候将这些实践经验落实到文字上,来和更多的朋友们进行交流了。
Albert陈凯
2018/12/05
7180
如何规范开发一个vue项目
在软件开发的浩渺星海中,编程规范如同航海的罗盘,为我们指引方向,确保我们的代码之旅能够顺利、高效地到达目的地。无论是个人开发者还是大型团队,编程规范都是提升代码质量、保障项目成功不可或缺的一环。
炑焽
2024/09/07
2940
我提交的 PR 为何还没能合入?
我提交的 PR 为何还没能合入?如何才能更快地合入我的 PR ? 相信这是很多参与开源项目的开发者常常遇到的疑问。
赵化冰
2024/03/26
1590
开发中的一些规范
代码评审(Code Review)是指在功能开发过程中,邀请原作者之外的开发者(审阅人)来对功能代码 进行评审的步骤。其目的是为了在代码合并入主线之前确保其质量,避免对主线代码的质量造成负面的影响。
后场技术
2020/09/03
7720
如何给开源社区提交代码
最近一段时间在做数据库相关,给一些开源社区提交过几个issue与pr,今天来简单复盘一下。
公众号guangcity
2023/11/14
1800
如何给开源社区提交代码
从亲身经历谈谈如何用Git分支解决项目生产实践中的痛点
最近笔者所在公司发生了一起小风波,事情大概是这样的:市场部老大在给客户现场演示系统时,正讨论着一个主题,恰巧系统在切换到相关功能时出现了异常,导致功能不可用,现场有点尴尬。
程序员白彬
2020/09/16
1.2K0
[译] 代码审查之最佳实践
原文:https://medium.com/palantir/code-review-best-practices-19e02780015f 作者:Robert F. (https://github.com/uschi2000)
江米小枣
2020/06/15
1.2K0
Google是如何做Code Review的?| CSDN原力计划
我和几个小伙伴一起翻译了Google前一段时间放出来的Google’s Engineering Practices documentation(https://github.com/google/eng-practices),翻译后的GitHub仓库:https://github.com/xindoo/eng-practices-cn,欢迎加star。目前只是翻译完了,因为译者水平有限,还需要审校。另外后续Google肯定还会有新内容放出来,欢迎想参与贡献的小伙伴加入,也欢迎在GitHub上加star。
AI科技大本营
2019/12/02
8230
TDesign——如何给TDesign提PR
思索
2024/08/15
1190
TDesign——如何给TDesign提PR
Ding!您有一份ChunJun实用指南,请查收
ChunJun 是易用、稳定、高效的批流一体的数据集成框架,主要应用于大数据开发平台的数据同步 / 数据集成模块,使大数据开发人员可简洁、快速的完成数据同步任务开发,供企业数据业务使用。
袋鼠云数栈
2022/08/19
3520
相关推荐
我们是怎么做Code Review的
更多 >
LV.0
这个人很懒,什么都没有留下~
领券
问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档