关于java:如何有效地进行代码-Review

40次阅读

共计 6758 个字符,预计需要花费 17 分钟才能阅读完成。

为什么要做代码 Review

为什么要代码 Review,置信每个人心中都有比拟统一的答案,Google 搜寻一下也能找到一大堆的文章。这里简略总结几点:

1)进步代码品质

这是代码 Review 的初衷,也是代码 Review 最间接的价值。Reviewers 依据各自的教训,思考形式,看问题的角度给代码提出各种可能的改良意见,从而造成更好的代码以及产品质量。

咱们晓得产品问题越晚提出解决它的代价就越大,参加进去的人、要走的流程都会越来越多。代码 Review 能够说是晚期解决问题最无效的路径之一了,在代码 Review 中解决掉哪怕一个小问题都能防止后续一堆的麻烦事。

2)造成团队对立的高质量规范

无效的代码 Review 最终会在团队范畴内建设起对立的质量标准,并且会随着团队成员的互相学习和促成造成更高的规范。参与者会在代码 Review 的过程中基于具体问题从不同角度提出改良意见,并最终做出以后最佳的抉择并造成共识。随着代码 Review 的无效进行,团队成员会无意识地关注代码品质,从而造成越来越高的事实上的质量标准。

3)集体疾速成长

通过无效的代码 Review,Author 和 Reviewer 都将取得成长,在 Review 过程中参加人就具体的问题开展深刻的探讨,无论是怎么写出整洁的代码、怎么更好地更全面地思考问题、怎么最佳地解决问题,参加人都能够相互舍短取长,相互进步。通过具体代码实现进行的探讨往往是最深刻和无效的,代码 Review 是开发者进步代码能力最重要的路径之一。

有的人认为代码 Review 就是 Reviewer 帮忙查找代码中的 Bug,其实代码 Review 不应该是一个单向的过程,而应该是个双向交流的过程,Reviewer 帮忙 Author 提出代码改良意见的同时,也是向优良的 Author 学习的过程。咱们都晓得进步代码能力一个无效的路径是浏览优良的我的项目代码,然而浏览我的项目代码有着不小的难度,这也是大部分人没有去执行的起因,而 Review 资深共事的代码,咱们在浏览代码的同时可能间接进行无效的沟通,这是一个疾速无效的学习路径,尤其对开发教训还不算丰盛的开发者而言。

如何做好代码 Review

2.1. 什么时候发动 Review

在代码 Review 上,Author 须要意识到:Reviewer 的工夫是低廉的。因而在正式邀请 Reviewer 发动代码 Review 前,Author 有几项须要留神的点,这些都能进步代码 Review 的效率,节俭 Reviewer 的工夫。

2.1.1. MR (Merge Request)

也称为 PR(Pull Request),MR 是咱们进行代码 Review 的中央,它记录着代码的具体改变,参与者具体的探讨过程。好的 MR 应该做到以下几点:

  • 繁多:一个 MR 应该只解决一个繁多的问题,无论是修复一个 bug,还是实现一个新 feature。Author 应该防止一个 MR 蕴含不同用意的代码改变。繁多的 MR 能帮忙 Reviewer 疾速地理解代码改变的动机,能有针对性地进行 Review。
  • 短小:MR 应该尽量地小,比方一个 feature 引入了较多的改变,须要思考是否能够拆成独立的几块实现,离开提 MR,比方接口定义、接口实现、逻辑对接等拆离开。
  • 具体: 这里说的具体是指 MR 应该尽可能地详细描述它的背景和动机,能够是在 MR 的形容中具体体现,也能够是连贯到具体 issue 或 tapd 单中。须要达到的目标是,其他人打开一个 MR 能晓得过后做这个改变的背景以及动机。

2.1.2. Commit Message

之前翻看了不少现存的我的项目代码,看到不少的 Commit Message 写得比较简单,例如一连串的 “update”, “fix”,从这些 Commit Message 中齐全看不出做了什么改变,想想如果之后想要定位之前的某个改变,该从哪里下手。

目前 Commit Message 标准比拟常见的有 Angular 团队的标准,并由此衍生出了 Conventional Commits Specification,能够参照此 Specification 约定 Commit Message 格局标准。

<type>(<scope>): <subject><BLANK LINE><body><BLANK LINE><footer>

大体分三行:

  • 【题目行】 必填, 形容次要批改类型和内容。
  • 【主题内容】 形容为什么批改, 做了什么样的批改, 以及这么做的思路等等。
  • 【页脚正文】 放 Breaking Changes 或 Closed Issues

其中 type 是 Commit 的类型,能够有以下取值:

  • feat:新个性
  • fix:批改 bug
  • refactor:代码重构
  • docs:文档更新
  • style:代码格局批改
  • test:测试用例批改
  • chore:其余批改, 比方构建流程, 依赖治理

其中 scope 示意的是 Commit 影响的范畴,比方 ui,utils,build 等,是一个可选内容。

其中 subject 是 Commit 的概述,body 是 Commit 的具体内容。

例如:

fix: correct minor typos in codesee the issue for details on typos fixed.Refs #133

Commit Message 能够在 git 中配置模板,这样能够在 vim 中展现出模板,另外可有工具帮忙咱们生成和束缚 Commit Message,例如 commitizen/cz-cli,这里不再具体阐明。

2.1.3. CI 通过

CI(Continuous Integration),继续集成能够帮忙咱们主动发现很多代码中的根本问题,在适合的动态代码查看(lint)配置和良好的单元测试笼罩下,CI 能够无效地进步代码的品质。很多人都低估了动态代码查看的能力,实际上当初常见语言的动态代码查看曾经能帮忙发现不少的 bug 和隐患。对于 Go 语言,能够配置 golangci-lint 来做代码查看,单元测试依据理论状况能够制订相应的规范,比方覆盖率 60%,其中要害的代码逻辑尽量全面笼罩。

提交代码 Review 前须要确保 CI 执行通过,这也是为了节俭 Reviewer 的工夫,可能通过自动化解决的事件,尽量不要让 Reviewer 来做,而 Reviewer 发现 CI 未过的 MR 也能够要求 Author 先解决 CI 问题。

2.1.4. Self-Review

咱们个别代码 Review 都是找别人来进行 Review,其实负责任的 Author 在邀请别人来代码 Review 前也须要本人简略 Review 一遍,即 Self-Review。

Self-Review 的目标包含:

  • 发现那些显著的忽略,如代码 debug 过程中留下的不必要的痕迹,比方 fmt.Println(…),不小心正文掉的代码。
  • 之前被 Reviewer 屡次提出过的问题。
  • Commits 是否失常,在多人合作的状况下 MR 中否带入了不相干的 Commit。
  • Commit Message 是否适合。

Self-Review 是一个十分疾速的过程,从我集体的教训,个别 1-2 分钟即可实现,所以举荐大家养成 Self-Review 的习惯。

2.2. 该找谁来 Review

从目标登程,能够从以下几方面思考 Reviewer:

  • 进步代码品质。所以首先应该找和代码改变严密相干的研发人员参加 Review,比方一起开发某个性能,某个我的项目,或者一起参加了方案设计探讨并给出了有价值意见的研发。
  • 获取意见。找有相干教训的资深研发帮忙 Review,比方 Java 语言资深的研发、写过雷同或相似零碎 / 性能的研发。
  • 造成共识。如果波及到不同团队或模块间的接口改变,或其余会影响其他人的改变,能够邀请相干团队或模块的接口人参加 Review,以对改变造成共识。
  • 品质把关。对于重要的代码库,可能会执行比拟严格的品质把控,如果设置了必须的 Reviewer,这些 Reviewer 也会参加进来。
  • 变动告知。很多状况下一个代码库可能只有一个人保护,如果做了些比拟非凡的变动,其他人很难发现。因而在做一些重要的然而了解起来不那么间接的中央的时候,最好告知一下相干的研发,以便他们能大略晓得产生了什么。

2.3. 都 Review 些什么

常常会有 Reviewer 拿到 MR 不晓得该 Review 些什么,其实无论你参加对应我的项目的深刻如何,都能够对代码进行 Review,也激励不同人从不同的深度、角度去帮忙 Review。代码 Review 没有固定的模式,它更像是一门艺术,惟一的进步方法就是理论参加进去。

Review 的时候能够从以下几个方面动手:

1)简略的 Review

在 CI 通过的状况下,最简略的 Review 形式可能只须要这样:

Reviewer:在理论环境中都验证过了吗?Author:当然验证过了 Reviewer:LGTM

这是一种揭示式的 Review。确认一句:是否在环境中验证过了,或者进一步把能想到的重要的验收点提出来确认一遍。即便是这种最简略的 Review 实际上也是有价值的,咱们很难保障所有研发都会在提 MR 前理论在环境中验证本人所做的批改,也很难保障单元测试、e2e 测试能 Cover 住所有的状况,Reviewer 基本上也不可能都本人去环境上跑一遍。让 Author 去确认实际上就是揭示 Author 去确保改变至多是真实有效的,尤其是对一些已公布版本的 Bugfix,肯定要揭示理论自测通过。

相似的揭示还包含:相干的文档(内部的)是否相应更新了、这个改变是否会有兼容性的问题、性能是否有影响。他们的实质就是揭示 Author 本人去思考他们可能脱漏的问题。

2)惯例的 Review

代码 Review 个别都会从代码格调、变量命名、语法对立处动手,当然这些应该更多的借助于 CI 等自动化伎俩来保障,然而在相干流程还不是很欠缺的前提下还是有必要进行关注。

此外代码可读性、代码健壮性、代码可扩展性都是 Review 时关注的点。每一个关注的点都依赖于 Reviewer 的理论教训,这里只简略举几个例子:

{代码可读性}

代码是写给人看的,因为没有不须要保护的代码,无论是 Author 本人后续保护代码,还是别人接手代码,能疾速地了解代码逻辑是十分必要的。

代码 Review 的时候能够关注以下几点:

  • 变量、办法的命名是否适合,是否实在反映了他们的目标,这方面网上能够找到不少的材料阐明。
  • 实现的逻辑是否已有现成的库能够代替。如果有成熟的库能够应用,尽量不要本人去实现,因为可能会引入不必要的 bug。从我集体的角度,简洁(大白话就是代码少)是可读性一个很重要的指标。
  • 对于正文。代码正文不求多,而在于无效,以前也经验过代码正文要求至多达到 30% 以上的年代,当初看来过多依赖正文其实是对代码品质的不自信,好的代码应该尽量做到自解释。在理论过程中偶然能看到代码逻辑理论曾经清晰明了,然而用语句不怎么通的英文正文了一通,最初反而是看懂了代码能力了解正文到底说了啥。因而 Review 的时候,不必要的正文能够倡议去掉。
  • 不好了解的中央要有失当的正文。代码中如果有非凡解决、非凡的常量、或者不合乎个别用法的逻辑须要特地正文阐明一下。
  • 代码的组织。良好的代码应该有较好的封装以及层级,使得代码看起来清晰明了,比方 DAO 层、Service 层。

{代码健壮性}

  • 代码的改变是否会影响其余性能。
  • 用户参数是否做和粗疏的校验。
  • 有没有 Panic 的可能(针对 Go 的说法)。
  • 是否会毁坏 API 的兼容性。

{可扩展性}

以后的实现形式是否能兼容当前相似的扩大需要。比方在新增接口、API 或者调整参数以解决某一问题上,能够思考是否后续会有其余相似状况产生。举几个例子:

  • 假如咱们须要定义一个 API 接口去获取一个用户的某些信息,例如联系方式等,咱们定义的 API 就不能只返回这些信息,而是应该把用户相干的信息都返回。
  • 假如我要定义一个参数,尽管以后定义成单个元素即可满足,例如 string, int,然而当前是否会波及到多个元素的场景,是否定义成 []stirng, []int 是更优的。

这里只是举了无限的一些例子,在理论 Review 过程中,Reviewer 能够依据本身的教训从各个角度提出优化的意见。个别须要重点看看:

  • 你看不懂或纳闷的中央。
  • 突破你惯例的中央。
  • 简单的中央。

2.4. 如何进行

Review 过程中激励 Reviewer 大胆 Comment,有不了解的中央,或者感觉不适合的中央都间接表达出来,Author 对 MR 的 每个 Comment 也要做出反馈,无论是展开讨论还是简略的给个 OK 都是无效的反馈。

Review 的过程能够是:

  • Author 在各项确认工作实现后,发动 Review,如果比拟急,能够给重要的 Reviewer 发消息申请帮忙 Review。
  • Reviewer 看到 MR 后应该先确认 MR 的背景和目标,如果不分明也无奈从 MR 中获取该信息,最好间接和 Author 沟通。
  • Reviewer 间接在 MR 上提出本人的倡议或者问题。
  • Author 对每个 Comment 进行反馈,并开展必要的探讨。
  • 简单的话题能够采纳线下探讨以进步沟通效率。
  • Author 解决完了所有的 Comment,也批改了代码后,须要在 MR 里 @ 一下相干 Reviewer 告知所有优化曾经提交,如果工夫比拟急也能够间接和 Reviewer 沟通。
  • Reviewer 确认没问题,给 MR 进行 Approve,个别简略的回复是 LGTM(Lood Good To Me),也能够对 Author 的工作进行赞叹,比方“God Job”等。
  • Approve 后 MR 由谁来合并这个看本人抉择。
  • 如果 Reviewer 提供了很多有用的倡议帮忙优化代码,Author 也能够礼貌性地感激一下 Reviewer。

2.5. 对于 Comment

代码 Review 很大水平上就是给代码挑毛病,而且个别预期挑的越多越好,但代码是 Author 写的,很多状况下或多或少会对 Author 造成不适。所以在 Comment 的时候须要尽量留神措辞,尤其是一些主观的货色,个别以倡议的形式给出。当然对于原则性的问题,是要坚守质量标准的,甚至能够间接 Deny 掉 MR。

另外,参与者也 不要悭吝你的溢美之词,无论是 Author 还是 Reviewer,在 Review 中发现了好的中央或好的倡议,请给予对方以必定和赞美,这样有助于 Review 无效的进行。

2.6. 参与者该抱着怎么的心态

2.6.1. Author

首先须要明确一点,是 Author 本人对代码的品质负责,因而该当怀着感恩的心去对待保持认真帮你 Review 代码的 Reviewer,因为并不是所有你加的 Reviewer 都有工夫和精力来帮你进步代码品质。

也正式因为 Author 是本人代码的 owner,所以不要依赖于 Reviewer 去帮你守代码品质的大门,像“代码 Review 的时候你怎么就没看进去”,“这不是你倡议我这么做的吗”这样的话千万别说。Reviewer 只是帮你进步代码品质,因而咱们该做的工作都要去做,比方粗疏的 Reviewer 可能某些状况下间接提出了代码优化的倡议,Comment 时贴上了优化的代码片段,Author 不能间接假如它肯定是能失常工作的,而应该对它进行残缺的验证。

对 Reviewer 给出的 Comment,不要有冲突的情绪,对你感觉不合理的倡议,能够婉转地进行回绝,或者具体阐明本人的认识以及这么做的起因。有时候一个你感觉不合理的倡议可能代表一个新的思考角度,也可能代表 Reviewer 本身代码能力上的有余,无论是哪个,无论最终是 Author 还是 Reviewer 失去了进步,都应该是坏事。

2.6.2. Reviewer

Review 代码既是帮忙进步代码品质的过程,也是 Reviewer 进步本人代码能力和沟通能力的过程。因而应该在 Review 的同时放弃一个学习者的心态,既要发现对方代码中的缺点,也要致力去发现代码中的亮点。切记单纯以挑毛病的心态去 Review 代码。

有不少 Reviewer 在写 Comment 的时候会犹豫,放心本人提出的问题或倡议比拟“蠢”,因而犹犹豫豫下看完了代码抱着一堆疑虑最终啥也没留下。其实在代码 Review 的时候大可不必有什么心里累赘,有什么纳闷的、不分明的中央或者有什么本人的想法,能够间接提出来,有时候一个简略的 Comment 就可能会激发 Author 和你的 Comment 毫不相干的新思路。再者你即便没帮 Author 进步代码,让 Author 帮你进步思考不也是建不错的事件吗。

Reviewer 也不须要去关注本人的“产出”,并不是肯定要提出一堆问题才是好的代码 Review,Author 代码写得很棒也是很失常的,如果从你的角度感觉代码没问题,大胆给个 LGTM 甚至是 Approve。

(完)

如果大家对 java 架构相干感兴趣,能够关注公众号 ” 架构殿堂 ”,会继续更新 java 根底面试题, netty, spring boot,spring cloud 等系列文章,一系列干货随时送达, 超神之路从此开展, BTAJ 不再是幻想!

正文完
 0