什么是CodeReview?为什么要CodeReview?

原创 admin  2023-02-10 16:35  阅读 393 views 次

年后公司开年会,很多人在会议上提到了需求文档,CodeReview等问题。基本就是代码的评审,平时中小公司一般没有代码的评审,为什么?

其实很多人都不是很重视CodeReview,因为CodeReview的效果短期很难看到,也很难量化衡量。就如同运动一样,偶尔过量的运动不仅对身体无益,可能还会起反作用,不过长期的坚持肯定会让你更健康,但能让你健康多少很难量化,不过前一段时间github上爆火的项目《程序猿延寿指南》里给出了可参考的数据,每周3次45分钟挥拍运动可以减少全因死亡率47%,按其公式折算大概增加9年的预期寿命。运动除了增加预期寿命外,也能显著减少很多疾病的发病率。坚持CodeReview如同坚持运动一样,趋势肯定是让整个代码库更为健康长寿。

为了提高代码质量,提高代码的可读性,容易维护性等还是要谈一谈CodeReview

1、什么是CodeReview?

Code Review(CR)即代码评审,又名代码走查,是一种通过复查代码来提高代码质量的过程,一般体现在一个团队的开发过程中。CR要求团队成员有意识地、系统地检查彼此的代码,从而验证需求、发现错误,同时指出其中不合规范的“低质量”代码,从而提高整个团队的代码质量。

一次 CR 可以是一次 Commit,也可以是一次 Merge Request。 也就是MR 评审以及 Commit 评审

2、为什么要CodeReview?

1.提升代码质量

假如将一个系统比作一个生命体,一行行代码比作一个个细胞,不好的设计宛如癌细胞,会逐渐扩散,终将杀死系统。而CodeReview的过程就像是T细胞吞噬掉癌细胞,保证系统的健康成长。让系统有更长久的生命力。

「没有人Review的代码,其代码水准就是写代码人的水准,而被一个团队Review过的代码,它的水准将接近甚至超过整个团队的最高水准。」

因为单个人可能在某些方便做的比较好,集大家之所长就能在各个方面都做的比较好。另外,随着CodeReview流程日常化,每个参与人的编码能力也会逐步提升,无限趋近于团队最高水准,因为在CodeReview的过程中,你可以看到别人做的好的地方,可以学习到经验,也可以看到别人做的不好的地方,吸取到教训。随着时间的流逝,逐渐积累为参与者的能力。

2.提前发现问题

在没有CodeReview流程的时候,我们都是依赖于测试,甚至是依赖于功能上线后用户暴露问题,这种发现方式已经偏晚了,尤其是让用户暴露问题的时候可能问题已经非常大了。「问题暴露的越晚,风险也就越大」。而CodeReview一般是放在代码测试之前,如果能在这个阶段就发现问题就能提前将各种风险扼杀在摇篮中。但是,CodeReview真的能提前发现问题吗?如果能的话,可以提前发现什么样的问题?

我个人觉得CodeReview可以提前发现流程或者实现上的问题,尤其是在做业务需求的时候,不同工作经验的人对同一个需求的理解肯定会有差异,代码实现上也会有很大的差异,有时候一点点的理解偏差,导致出现那种失之毫厘谬以千里的后果,写代码的人也会因为处在自己的思维定式中发现不了问题,而别人可能因为经验丰富或者需求相关背景了解更多,就能很轻易发现问题。像这种情况一般出现在团队新人身上,他们对已有系统和业务了解不多,实现需求时很容易出现问题,这时候如果有人帮忙指出就能避免更严重的后果,另外也有助于新人了解业务和融入团队。

在CodeReview过程中另外一种问题也比较容易发现,就是那些别人之前踩过的坑。比如Java中SimpleDateFormat其实有线程安全的问题,不了解的人很容易就踩坑了。如果别人踩过这个坑,就可以在CodeReview过程中提前帮你指出来。很多开源的类库,甚至Jdk中很多包或多或少都有使用上的坑…… 这种例子就数不胜数了。

当然CodeReview也不是万能的,也有很多问题发现不了的,比如一些边缘Case或者是代码计算结果的准确性,比如你代码实现了一个很复杂公式的计算,你总不能指望有人能通过看代码来发现问题吧。这些还是老老实实去做测试吧!

3.经验和知识的传递(可读性可维护性)

程序猿可以写出能运行的代码,但真正的工程师才能写出低bug、易扩展、易维护的高质量代码,更高级的工程师还能帮其他人成为一名合格的工程师。CodeReview的流程也是高级工程师来帮助其他人最直接的方式。

在CodeReview中,你可以看到其他人写出来的优秀代码、优秀的设计,甚至和改动相关的业务背景知识……,Review越多,学到的也越多。另外,即便是哪些不太好的代码,经过别人的Review,必然会留下很多评论或者是改动建议,甚至是别人之前踩的坑,你都能看到,从这些内容上你也可以学到很多新的知识。CodeReview不仅仅是一个提升代码质量方式,它也可以肩负起知识积累和消息集散的功能。

举个我之前遇到过的例子,我们之前有个功能需要操作机器上的文件,当然用Java的File也能实现,但是对操作多层级的文件夹时就很不方便了,需要自己写很多的代码,搞不好还容易出bug。后来我发现apache-common包中提供了IOUtils类,可以很方便操作文件夹。我把这个写到CodeReview的评论中,只要看到过的人都会知道原来有这个东西可以用。

所以,Review别人代码时请毫不吝啬地留下你的建议吧,另外,CodeReview时也不要忘记关注下别人的建议,说不定可以学到新的东西。

4.互相学习

(1)旁观者清。

对于同一段业务代码,由于看待问题的角度不同,评审者可能会比开发者更容易发现其中的问题,或是找到更有效的解决方案,共同维护团队的代码质量。

提高代码质量和可维护性, 可读性等。

查漏补缺, 发现一些潜在的问题点等。

最佳实践, 能够更好更快的完成任务的方法。

知识分享, Review他人代码时, 其实也是一个学习的过程, 自己也会反思&总结。

(2)快速了解业务。

理想状态下,团队中的每个人都需要对整个项目的各个部分都很熟悉,当然,在项目很大时这是不现实的。通过代码审查至少可以让每个人了解更多的业务模块,同时也能达到人员互备的目的。

人员互备:通过 CR,评审者也相当于参与了这次开发,相当于一种人力“备份”,当你休假或正在忙别的需求的时候,这时“备份”或许就能帮上你的忙了。

(3)开发者能够学习获得什么?

对需求的理解得到加深。

表达能力得到加强。

逻辑能力得到训练。

心理承受能力得到提高。

(4)评审者能够学习获得什么?

快速上手业务需求和全局的架构。

统一大家约定俗成的代码风格。

优秀的设计思路和业务逻辑。

JavaVSPythonVSPHP

三.如何做好CodeReview ?

CodeReview的步骤与原则

了解改动的背景

CodeReview不是一上来就看代码,这样有可能你会看的云里雾里,纯粹是浪费时间。CodeReview虽然是Review代码,但是首先你的知道你要看的代码实现了什么样的功能,是在什么样的背景下去做的,清楚前因后果之后,你才能知道这个代码大概应该怎么去写,你才能更好的去Review别人的代码、去发现别人的问题。

纵观全局

知道背景之后,在你脑海中就会有一个大概的编码思路,也有个流程主线。这个时候可能有两种情况,你和写代码人的思路相同,那你就顺着你们共同的思路去帮忙Review整个流程是否正确。另一种情况就是你们思路不同,你就得看代码去了解写作者的思路,然后确认是谁的思路有问题,或者是谁的思路更好,然后同写作者一起将这个流程优化到更优。

逐层细化

确定完整个流程之后,就可以逐步深入到代码细节中了,细节可以Review的地方就很多了,可以看下下一节的内容,这里就先不展开了。

CodeReview的关注点

在CodeReview的过程中,如果有一些立足点的话可以帮助大家更好的完成CodeReview的过程,我大概总结出以下几点:

「功能性:」 代码所实现的功能是否和预期一样,是否实现了所有必须的功能?

「复杂性:」 功能实现是否过于复杂?过于复杂的代码更容易出问题,而且可维护性也会更低。

「代码风格:」 代码是否符合团队编码规范?

「文档&注释:」 如果代码功能有改动,关注下相关文档和注释有没有同步改动。错误的注释和文档可能会让未来的开发者产生理解成本。

「代码亮点:」 如果你看到变更中做得好的地方,也别吝啬你的赞美。

上面描述更偏概括性,我们来举一些更详细的例子,帮助大家理解上面几点。

代码设计良好,可读性和可维护性高。

是否有线程安全的bug。

代码没有增加不必要的复杂性。

开发者没有写一些目前没有在用的代码,这种无用的代码未来大概率也不会用,所以不要假设。

代码有适当的单元测试。

测试逻辑设计良好。

开发者使用了清晰明了的变量和函数命名。

注释清晰明了且实用,并且解释清楚了为什么这么做,而不仅仅是做了啥。

代码有相应完善的文档。

代码风格符合规范。

代码有没有更优的实现?(性能、资源占用……)

(1)CR 是必要的,但也需要结合团队现状。

当你的团队开发任务极其紧张,再耗费一部分人力去进行 CR,是不明智的。

(2)所有的代码都应被赞成。

因为团队代码库的每一次改动(Change List ,以下简称 CL),都必定会提高当前系统的整体质量,即使这个 CL 并不完美。

(3)CR 不应该追求完美,而应追求持续改进。

要知道,没有完美的代码,只有更好的代码,“慢即是快”。

(4)CR 不是挑刺,更不是证明谁的能力更强。

CR 是为了提高整个团队的能力,而不是针对个体设置的检查“关卡”,仅具有指导意义。

(5)评审者也需要对这个 CL 负责。

CR 不应设置奖惩机制,即便是有,也是对评审者和开发者同时的奖励或处罚。

(6)时刻保持谦虚。

无论是评审者还是开发者,都可以在 CR 中提升自己的能力。

(7)合理解决问题

解决冲突难以达成共识时,需要面对面或者拉起更大的团队讨论,带上leader。

四.在一次CodeReview中我需要关注什么?

(1)git 提交规范

(2)代码风格

a. 可读性

衡量可读性, 有很好的实践标准, 即 Code Review 时能否非常容易的理解代码逻辑, 如果不能, 那意味着代码的可读性要进行改进。

b. 命名

描述是否准确。不建议使用生僻单词。

命名格式是否与团队风格一致。

c. 函数体长度/类长度

函数体太长,不利于阅读。一般建议不超过50行。

类太长,有可能违背“单一职责原则”。

d. 参数个数

参数不要太多。一般不超过5个;5个以上建议使用对象。

e. 注释

恰到好处的注释,能够帮助评审者更好地理解函数体和类。

(3)架构/设计

a. 单一职责原则

一个类只做一类相关的事情。

一个方法,最好只做一件事情。

b. 行为是否统一

校验处理是否统一。

数据处理是否统一。

错误处理是否统一。

c. 代码是否污染

代码是否对其他模块有强耦合。

d. 是否有重复代码

检查是否将可复用的方法或组件抽取出来。

e. 开放-封闭原则

代码是否具有良好的可扩展性。

f. 代码健壮性

核心数据有没有强制校验。

边界值有没有考虑得当。

有没有潜在的bug。

有没有内存泄露。

有没有循环依赖。

g. 是否考虑了错误处理

有没有很好的 Error Handling。

h. 面向接口编程

检查业务的实现中有没有进行合适的抽象。

i. 效率/性能

对用户使用频率高、资源消耗大的业务部分是否处理得当。

关键算法的时间复杂度。

有没有潜在的性能瓶颈。

j. 代码重构

新的改动是打补丁,让代码质量继续恶化,还是对代码质量提升有帮助。

k. 时间粒度。

一个Review单元的时间应控制在10~20分钟,如果超出这个时间,那么这段代码本身可能在业务划分或代码实现上,是存在问题的。

 

本文地址:https://www.moonpm.com/1090.html
关注我们:请关注一下我们的微信:扫描二维码产品设计研究与产品经理交流中心 (鼠标移入红色字)
版权声明:本文为原创文章,版权归 admin 所有,欢迎分享本文,转载请保留出处!

发表评论


表情