新闻资讯

新闻资讯 媒体报道

前端干货:如何让你的代码评审人喜欢上你?

编辑:005     时间:2020-12-14

前言

多替对方考虑一下。现在想看看代码评审的直播,不知道有没有?今日前端早读课由@排骨翻译投稿分享。

正文从这开始~~

当人们谈论代码审查时,往往关注的是审查人员。但是编写代码的开发人员和阅读代码的人员对于评审来说同样重要。几乎没有任何关于如何准备代码进行评审的指导,所以作者常常由于完全的无知而把这个过程搞砸。

本文描述了作者参与代码审查的最佳实践。事实上,在这篇文章的最后,你会非常擅长发送你的代码供评审,以至于你的评审员会爱上你。

但我不希望我的评审员爱上我。

他们会爱上你的。处理它。没有人在临终前抱怨过有太多的人爱上了他们。

为什么要改进代码评审?

改进代码评审技术可以帮助您的评审人员、您的团队,最重要的是: 帮助您。

更快地学习: 如果你正确地准备了你的变更列表,它会引导你的评审人的注意力到支持你成长的领域,而不是无聊的风格违规。当你表现出对建设性批评的欣赏时,你的评审人会提供更好的反馈

让别人变得更好: 你的代码审查技术为你的同事树立了一个榜样。有效的作者实践会影响到您的队友,当他们向您发送代码时,这会使您的工作更加容易。

最小化团队冲突:代码审查是一个常见的摩擦源。慎重而认真地对待它们,可以最大限度地减少争论。

黄金法则:珍惜评审人的时间

这个建议听起来很明显,但我经常看到作者把他们的评审人当成个人质量保证技术人员。这些作者根本不努力去发现自己的错误,也不努力去设计他们的修改清单以保证可审性。

你的同事每天上班时,注意力时间是有限的。如果他们把其中的一部分分配给你,那就不能把时间花在自己的工作上。你要让他们的时间价值最大化,这才是公平的。

当双方参与者相互信任时,评审会大幅提高。当你的评审员指望你认真对待他们的反馈时,他们会付出更多的努力。把你的评审员看作是你必须克服的障碍,就会限制他们为你提供的价值。

1. 先回顾自己的代码

在给同事发送代码之前,自己先阅读一下。不要只检查错误--想象一下第一次阅读代码。哪些地方可能会让你感到困惑?

我发现在写代码和审查代码之间休息一下是很有帮助的。经常在一天结束的时候发布他们的修改,但这时你最有可能忽略掉粗心的错误。等到第二天早上,再把它交给你的队友之前,用新的眼光看一下变更列表。


尽可能地采用你的评审人的环境。使用他们会看到的相同的 diff 视图。在 diff 视图中比在常规的源代码编辑器中更容易发现愚蠢的错误。

不要期望自己是完美的。不可避免的是,你会在发送的变更列表中包含你忘记删除的调试代码,或者是你想排除的杂乱文件。这些错误并不是世界末日,但值得追踪。注意你的错误模式,并考虑创建系统来防止它们。如果它们发生得太频繁,就会向你的评审人发出信号,表明你不珍惜他们的时间。

2. 写出明确的变更清单说明

在我的上一份工作中,作为开发人员指导计划的一部分,我定期与一位高级工程师见面。在我们第一次见面之前,他让我带一份我写的设计文档。当把文档交给他时,我解释了这个项目是什么,以及它如何与我的团队目标相一致。我的导师皱起了眉头。"你刚才告诉我的所有内容都应该写在你的设计文档的第一页,"他直截了当地说。

他说得没错。在写设计文档时,想象着我的同事会如何阅读它,但没有考虑到其他读者。除了我的直接队友之外,还有更广泛的读者,包括伙伴团队、导师和推广委员会。他们也都应该能够理解这份文件。自从那次讨论之后,我总是在思考如何构思我的工作来解释其背景。

你的变更清单描述应该总结读者需要的任何背景知识。当你写描述时,你可能会想到一个代码评审员,他们不一定有你想象的背景。此外,你的其他队友可能也需要阅读这个变更列表,未来的读者在回顾变更历史时应该理解你的意图。

一个好的变更清单描述能从高层次上解释这个变更实现的目标,以及你为什么要做这个变更。

想深入了解如何写出优秀的变更列表描述,可以参考Chris Beams的《如何写Git Commit Message》和David Thompson的《我最喜欢的Git commit》。

3. 把简单的事情自动化

如果你依赖你的评审员来告诉你,你的大括号在错误的行上,或者你的改变破坏了自动化测试套件,你就是在浪费他们的时间。

自动测试应该是你团队标准工作流的一部分。在持续集成环境中,所有自动化检查通过后,审查就开始了。

如果您的团队被严重误导,拒绝投资于持续集成,那么您可以自动执行这些检查。向开发环境中添加 git pre-commit hooks、 lents 和 formatter,以确保代码遵循适当的约定,并在每次提交时保留预期的行为。

4. 用代码本身回答问题

这张图有什么问题?

作者帮助我理解了这个功能,但下一个读它的人呢?他们是否应该深入到变更历史中,阅读有史以来的每一次代码审查讨论?更糟糕的是,当作者走到我的办公桌前给我当面解释时,既打断了我的注意力,又确保了其他人永远无法获得这些信息。

当你的评审人员表示对代码的工作原理感到困惑时,解决的办法不是向那个人解释,而是需要向所有人解释。

回答别人问题的最好方法是重构代码,消除混乱。你可以重新命名一些东西或重组逻辑,使其更加清晰?代码注释是一个可以接受的解决方案,但严格来说,它们不如代码自然地记录下来。

5. 狭义范围的变化

范围蔓延是代码审查中常见的反模式。开发人员开始修复逻辑错误,但是他们注意到过程中的 UI 缺陷。“我在这儿的时候,”他们想,“我会把另一件事情搞定的。”但现在他们把事情搞得一团糟。他们的评审人必须弄清楚哪些变化服务于目标 a,哪些服务于目标 b。

最好的变更列表只做一件事。变更越小、越简单,评审人就越容易把所有的上下文都记在脑子里。将不相关的变更解耦,还可以让你在团队成员之间并行审查,减少变更的周转时间。

6. 将功能和非功能变化分开

最小化范围的必然结果是分离功能和非功能的变化。

没有代码审查经验的开发人员经常违反这个规则。他们会做一个两行的修改,然后他们的代码编辑器会自动重新格式化整个文件。开发人员要么没有认识到他们做了什么,要么决定新的格式化更好。他们发出的两行功能变化被埋在数百行非功能的空白变化中。

你能发现埋藏在这个变更列表的空白噪音中的功能变更吗?

乱七八糟的变更列表是对你的评审人的巨大侮辱。仅有空格的更改很容易检查。两行的变化很容易检查。两行函数的改变丢失在空格的海洋变化是乏味和疯狂的。

开发人员在重构时也往往会不适当地混合变化。我喜欢我的队友重构代码,但我讨厌他们一边重构一边改变代码的行为。

这个变更列表对行为做了一个单一的变更,但重构的变更却把它掩盖了。

如果一段代码需要重构和行为变化,它应该发生在两到三个变更列表中。

  • 增加测试来行使现有的行为(如果他们还没有)。

  • 重构生产代码,同时保持测试代码不变。

  • 改变生产代码中的行为,并更新测试以匹配。

通过在第2步中保持自动化测试不变,你向评审员证明了你的重构保留了行为。当你到达步骤3时,你的评审员不必把行为变化和重构变化分开,因为你已经提前把它们解耦了。

7. 将大的变更清单分开

过大的变更列表是范围蔓延的丑陋表兄弟。假设一个开发者发现,为了引入特性X,他们必须修改现有的库A和库B的语义。如果是小范围的修改,那还好,但是过多的修改会使变更列表变得巨大。

一个变更清单的复杂度会随着它所触及的代码行数成倍增长。当我的修改超过400行生产代码时,我就会在请求审查之前寻找机会把它拆开。

你能不能不一次性改变所有的东西,而是先改变依赖关系,然后在后续的变更列表中添加新功能?如果你现在添加一半的功能,而在下一个变更列表中添加另一半的功能,你能不能保持代码库的正常状态?

把你的代码拆分开来,找到一个子集,做出一个可行的、可理解的改变,这很繁琐,但它能产生更好的反馈,给你的审稿人带来更小的压力。

8. 大方回应批评

毁掉代码审查的最快方法就是把反馈当做个人。这很有挑战性,因为许多开发人员为自己的工作感到自豪,并将其视为自己的延伸。如果你的评审人毫无技巧地将他们的反馈框定为人身攻击,那就更难了。

作为作者,你最终要控制自己对反馈的反应。把评审人的笔记当作是对代码的客观讨论,而不是你个人的价值。做出防御性的回应只会让事情变得更糟。

我试着把所有的笔记解释为有用的教训。当评审人在我的代码中发现了一个令人尴尬的bug时,我的第一反应是找借口。相反,我会抓住自己,并赞扬我的评审人的严谨态度。

当你的评审人在你的代码中发现一个微妙的bug时,要表示感谢。

令人惊讶的是,当你的评审人发现代码中的细微缺陷时,这是一个好的迹象。这说明你的变更列表包装得很好。没有了所有明显的问题,比如糟糕的格式化和混乱的名称,你的评审人可以把注意力深入到逻辑和设计上,产生更有价值的反馈。

9. 当你的评审人出错时要有耐心

评审人时常会出现完全错误的情况。就像你会不小心写出错误的代码一样,你的评审人也会误解正确的代码。

许多开发人员对评审人的错误做出了防御性的反应。他们认为这是一种侮辱,因为有人会用甚至不是真的批评来侮辱他们的代码。

即使你的评审人搞错了,那也是一个危险的信号。如果他们看错了,其他人会不会也犯同样的错误?读者是否必须进行异常程度的审查,以保证自己不存在某个bug?

当你的评审人犯错时,要抵制诱惑来证明他们是错的。

寻找重构代码的方法,或添加注释,使代码更明显地正确。如果混淆源于晦涩的语言特征,使用非专家可以理解的机制重写你的代码。

10. 明确地传达你的回应

我经常会遇到这样的情况:我给别人做了笔记,他们更新了代码,解决了我的一些反馈,但他们没有写任何回复。现在,我们处于一个暧昧的状态。是他们错过了我的其他笔记,还是他们还在工作?如果我开始新一轮的审查,我有可能在一个半成品的变更清单上浪费时间。如果我等待,我可能会造成一个僵局,我们两个人都在期待对方继续。

在你的团队中建立惯例,明确谁在任何时候都是 "拿着指挥棒"。要么作者在进行编辑,要么评审人在写反馈。绝不应该出现因为没有人知道谁在做什么而导致流程停滞的情况。你可以通过修改清单级别的注释来轻松实现这一点,这些注释表明了你何时来回交接控制权。

当你把控制权交还给评审人时,要在变更清单上发表评论,以明确沟通。

对于每一个需要操作的注释,都要明确回应以确认您已经处理了它。一些代码审查工具允许你将注释标记为已解决。否则,对每个注释遵循一个简单的约定,比如 "完成"。如果您不同意该注释,请礼貌地解释为什么您拒绝采取行动。

像Reviewable和Gerritt这样的代码审查工具为作者提供了将特定注释标记为已解决的机制。

根据评审人的努力来调整你的回应。如果他们写了一个详细的注释来帮助你学习新的东西,不要只是标记它完成。深思熟虑地回应,对他们的努力表示感谢。

11. 艺术地征集缺失的信息

有时候,代码审查说明会留下太多的解释空间。当你收到 "这个函数很混乱 "这样的评论时,你可能会想知道 "混乱 "到底是什么意思。是这个函数太长了吗?名字不清楚吗?是否需要更多的文档?

很长一段时间,我都在努力澄清模棱两可的注释,而不至于让人听起来有防备。我的本能是问:"这有什么好困惑的?"但这显得很暴躁。

有一次,我无意中给队友发了一张模糊的纸条,他的回复让我觉得梦幻般的违和感。

哪些改变会有帮助?

我很喜欢这种回复,因为它标志着一种不设防的态度和对批评的开放。每当评审人给我不明确的反馈时,我总是用一些变化来回应:"什么会有帮助?"

另一个有用的技巧是猜测评审人的意图,并根据这个假设主动编辑你的代码。对于像 "这很混乱 "这样的注释,请再看一下你的代码。通常,你可以做一些事情来提高清晰度。修改向你的评审人传达了你是可以修改的,即使它不是他们心目中的那个。

12. 授予所有与你的审查员的联系

在网球比赛中,当你不确定对手的发球是否落在界外时,你会给他们疑虑的好处。对于代码审查也应该有类似的期望。

美国网球协会要求球员在进行线路判罚时,要给对手好处。

关于代码的一些决定是个人品味的问题。如果你的评审人认为你的8行函数作为两个5行函数会更好,那么你们两个人都不是客观上的 "正确"。哪一个版本更好,这是一个意见问题。

当你的评审人提出建议,而你们每个人都有大致相等的证据来支持你的立场时,请服从你的评审人。在你们两个人之间,他们有更好的视角,可以从新阅读这段代码的感受。

13. 尽量减少各轮审查之间的滞后期。

几个月前,一个用户为我维护的一个开源项目贡献了一个小改动。我在几个小时内就给了他们反馈,但他们很快就消失了。几天后,我又检查了一遍,仍然没有任何回应。

六周后,那个神秘的开发者再次出现,提交了他们的修改意见。虽然我很感激他们的努力,但两轮审查之间的滞后使我的工作量增加了一倍。我不仅要重新阅读他们的代码,还要重新阅读我的反馈,以恢复我对讨论的记忆。如果他们能在一两天内跟进,我就不用做这些额外的工作了。


六周的暂停是极端的,但我经常看到团队成员之间长时间的、不必要的拖延。有人发送了一份变更清单供审查,收到反馈后,又因为另一项任务分散了他们的注意力而将其搁置了一周。

除了恢复上下文所损失的时间外,半成品的变更清单还增加了复杂性。它们使每个人都很难跟踪哪些已经合并,哪些正在进行中。有了更多的部分完成的变更列表,就会有更多的合并冲突,而没有人喜欢修复这些冲突。

一旦你把代码发送出去,推动审查完成应该是你的最高优先级。你端的延迟会浪费审稿人的时间,并增加整个团队的复杂性。

结论

当你准备下一个变更清单进行评审时,请考虑你所控制的因素,并利用这些因素来有效地指导评审。当你参与评审时,寻找那些阻滞进度或浪费精力的模式。

记住黄金法则:珍惜审阅者的时间。当你允许审稿人专注于你代码中有趣的部分时,他们就会产生高质量的反馈。如果你要求他们解开你的代码或纠正简单的错误,你们都会受到影响。

最后,深思熟虑地沟通。简单的沟通不畅或不经意的评论很容易使评审脱轨。当评论别人的作品时,情绪会很激动,所以要注意那些可能让你的审稿人感到被攻击或不尊重的陷阱。

祝贺你!如果你已经达到了这个程度,那么你就应该把你的作品交给他。如果你已经达到了这一点,你现在是一个专业的评审人。你的评审人很可能爱上了你,所以要好好对待他们。



本内容属于网络转载,文中涉及图片等内容如有侵权,请联系编辑删除

郑重声明:本文版权归原作者所有,转载文章仅为传播更多信息之目的,如作者信息标记有误,请第一时间联系我们修改或删除,多谢。

回复列表

相关推荐