原文标题:The gentle art of code review
如果程序员彼此喜欢,他们会玩一个叫做"结对编程"的游戏。如果没有,那么这个游戏就叫做"同行评审"。 ------ ---Anna Nachesa - 安娜·纳切萨
"野蛮"、"踩雷"、"令人沮丧"("Brutal". "Minefield". "Frustrating".)在被要求描述他们的代码审查经历时,所有这些词都比我在本文标题中使用的词更夸张。为什么呢?
为什么代码审查会做的如此糟糕,我们能做些什么呢?
代码审查是软件开发的一个必要部分,但是当代码审查做得不好时,它会导致大量的摩擦、焦虑、冲突以及浪费时间和精力。
我们怎么才能做得更好呢?我们是否能够以仁慈、温柔、谦卑和同情的态度给予和接受代码评审?什么样的注释可以为代码增值,并与同事建立信任和安全感?我们如何强调积极的一面,安抚受伤的虚荣心,并在不树敌的情况下表明立场?
变更集的生命和时间
让我们从代码审查开始讨论什么是代码审查以及什么时候发生。我们将使用我的三个朋友 Aisha、Bryan 和 Chiku 作为我们的例子。
工作流通常是这样的:Aisha 编写一些代码(或者 Aisha 和 Bryan 结对编写一些代码),它被签入版本控制,通常在一个分支上。Aisha 现在可以发出一个 pull request,也称为 merge request,当 Chiku 批准时,它将把她所有的变更(她的变更集)与主线合并。
或者,一些团队直接将更改推送到主线,有时也会定期将其拉入发布分支以构建版本化发布(如果需要)。无论哪种方式,通常都有一个必须批准变更集的步骤,可能是由更高级的人批准,但通常只是由团队中的其他人批准。
作为批准的一部分,Chiku 应该审查代码,其中"审查"至少意味着"阅读",但最有可能也会提出意见或询问有关代码的问题。然后,Aisha,Bryan 和 Chiku 之间进行了对话,通常会进行一些进一步的更改,然后合并最终获得批准。
结对评审
请注意,我们并没有说这个对话需要通过版本控制软件本身进行:例如,作为 GitHub 拉取请求的注释。实际上,最好的方式是通过交谈,与那些小文本框相比,这是一个难以置信的高带宽通信渠道。
换句话说,代码应该是成对审查的,也应该是成对编程的。例如,Aisha 和 Chiku 可以共享屏幕,一起查看代码,提出问题,提出建议,解释歧义,并突出潜在的问题。
通过语音同步进行这样的交流要快得多:
CHIKU:
int
向下转换安全吗?如果值大于 32 位呢? AISHA: 不可能,因为如果你看这里,它来自...... CHIKU: 哦,我现在明白了。如果我们在这里加一个评论,只是为了明确这一点? AISHA: 当然...
这只花了我的手表 15 秒,但如果他们不得不通过 GitHub 评论绕这个循环几次,它可能会把合并推到周二。另外, Aisha 和 Chiku 可能仍然是好朋友,而漫长的代码审查辩论已经危及到即使是最好的关系。
语调甚至面部表情传达了很多额外的信息,否则这些信息就会丢失,不知何故,人们在面对面时总是比来回打字时更温柔、更尊重对方。
也许正是出于这个原因,有时候你会遇到一些人坚持尝试使讨论异步和纯文本。挫败这种策略的最简单方法就是不要加入。如果他们通过 GitHub 或电子邮件向您发送对代码的评论,只需亲自联系他们并要求进行交谈。
如果他们还是不愿意,那就这样吧。很明显他们不想和你谈话;他们只想在你欣赏的时候说话。这不太可能有帮助,所以你应该完全绕过他们,找一个对关于代码的真正对话感兴趣的人。
随着时间的推移,您将与可以与您"结对审查"代码的人建立起一个有用的关系网络,结果您的代码(他们的代码也会更好)。
使用注释增加价值
但是,像这样的成对审查并不总是可能的,所以当代码审查是以文本形式进行的时,这意味着我们需要更加注意我们说的是什么以及我们如何说的。我们从"什么"开始吧。
考虑代码评审的一个好方法是将其视为为现有代码增值的过程。所以你要发表的任何评论最好都是这样。以下是几种表达方式,你在审阅他人代码时可能会有不同的反应:
- 不是我的风格。每个人都有自己的风格:他们特别喜欢的命名、安排和表达它们的方式。如果你没有编写这段代码,它就不会符合你的风格,但没关系。你不需要评论改变代码以符合你的风格不会增加价值。别管了。
- 不明白这是干什么的。如果你不确定代码实际上说了什么,那就是你的问题了。如果你不知道某个特定的语言语法是什么意思,或者某个函数是什么作用的,就去查一下。作者是想让他们的工作完成,而不是教你如何编程。
- 我不明白它为什么会这样。另一方面,如果你不能弄清楚为什么代码会说什么,你可以问一个问题:"我不太清楚这是什么意图。有什么我没看到的吗"通常是有的,所以要求澄清,而不是标记为"错误"。
- 还可以更好如果代码基本上没问题,但你认为有更好的方法来编写它,这不仅仅是一个风格问题,那么把你的建议变成一个问题。"写......会不会更清楚?你认为X是...更合乎逻辑的名称吗?重新使用这个变量会更快吗?还是这不重要?"
- 需要考虑的事情。有时候你有一个想法可能会有帮助,但你并不确定。也许作者已经想到了这个想法并拒绝了它,或者他们只是没有想到。但你的评论很容易被解释为批评,所以要尝试性地温和地说:"我突然想到,在这里使用
sync.Pool
可能是一个小小的改进,但也许这只是矫枉过正。你觉得怎么样?" - 别以为这是对的。如果你觉得代码不正确,或者不应该存在,或者有一些应该存在的代码缺失,那么再次,让它成为一个问题,而不是指责。"我们通常不是要检查这个错误吗?有什么理由不需要在这里吗?"如果你错了,你就给自己留下了一条优雅的退路。如果你是对的,你已经巧妙地表明了一个观点而没有树敌。
- 错过了什么。代码就其本身而言是很好的,但是有些情况作者没有考虑,或者一些重要的问题他们忽略了。使用"是的,然后......"技巧:"这在正常情况下看起来很好,但我想知道如果这个输入真的很大,会发生什么?你想不想..."
- 这绝对是错误的。作者只是说漏嘴了,或者有你知道而他们不知道的事。这是你的机会,以所有应有的仁慈和谦卑来启迪他们。不要只是喋喋不休地说出了什么问题;花点时间仔细、优雅地表达你的回答。再次,使用问题和建议。"看起来我们在这里记录了错误,但无论如何都要继续。如果结果是
nil
,那么这样做真的安全吗?你觉得在这里返回错误怎么样?"
强调积极因素
我们经常认为代码审查是一个指出错误的过程,但也有一个很好的机会来赞扬正确的东西。实际上,您的审查应该从描述您喜欢的代码的所有内容开始。"这真的组织得很好,我喜欢你如何使用X,Y和Z为读者给予额外的上下文。函数名很棒,这似乎是一个很好的 API 使用。
一勺糖可以帮助药效下降,即使你不得不给予别人一些难以听到的反馈,你也总能找到一些好的东西说出来。用积极的一面来引导,跟进你的委婉、尊重的评论和建议,最后用一些令人鼓舞的东西来结束复习:"干得好!这真的很好。"
但是,如果您正在审阅比您更高级的人的代码,那么告诉他们他们做得很好可能并不合适。他们可能会觉得,无论对错,你还没有资格去判断。相反,你可以这样说:"我真的从中学到了很多东西,谢谢你给我机会看看它。"
当你的虚荣心受到伤害
你的自尊心会从代码审查中受到打击,特别是当代码审查没有被巧妙地完成时,这会伤害你的自尊心。
你把你的心和灵魂投入到一件作品中,你怀着美好的期望把它送出去,希望它会被誉为一场胜利,然后它回来时却带着残酷的评论。
你感到受伤,你感到愤怒和怨恨,你试图反击。"是吗?"我告诉你,我是真的爱你。"
不用说,这不是个好主意。你的评论者几乎可以肯定是出于好意,即使它没有给人以这种方式。如果他们的本意不是好的,他们打算自己的言论是轻蔑和伤害,那么当然,他们是一个混蛋。
但这个世界充满了混蛋。把他们都变成正派人不是你的工作,你当然也得不到报酬。
相反,你就忍着吧,继续前进。他们的反馈可能比你一开始准备承认的更多的真实性,即使它是以不必要的粗糙的方式表达的。
不是每个人都是人际交往的高手,即使是最善良的同事也可能因为与你或你的拉拉请求完全无关的原因而度过一天。如他们所说,这是宽恕:如果我们能真正了解一个人内心的秘密,我们就不会对他有什么苛刻的想法。
"我知道你想干什么了"
有些人的代码审查评论虽然不完全粗鲁,但可能非常居高临下,这几乎同样糟糕。你知道这种事:"嘿,你可能没有意识到这一点,但你应该在这里使用指针接收器。我来教你怎么做......"
也许他们是想表现得友好些,但实际上,我们听到的是"你不知道你在做什么。幸好我在这里救了你,让你免于出丑。"的确.有趣的是,这种行为的人通常自己并不知道很多,也许这就是为什么他们会这么快地向别人指出他们不知道的事情。
这种情况在科技行业经常发生,你会发现,那些最懂的人往往不会说太多,而那些什么都不懂的人似乎一直在说话。
也许这是因为,在科技行业,人们往往可以不知道自己的无能。并非所有行业都如此宽容。
例如,在航空领域,那些大大高估自己技术水平的人都死了。-- 菲利普·格林斯潘(Phillip Greenspun),摘自杰西卡·利文斯顿(Jessica Livingston)的《Founders at Work》
风格挑剔
我们在前面看到,"不是我的风格"注释并不能真正为代码增值;他们只会制造混乱。每当这段代码被更新时,它也会累积一些浪费性的和随机的更改,以适应碰巧审查它的人的"风格"。所以,虽然你不会给出这些评论,但当你收到它们时,你应该怎么做?
我的建议,似乎有点激进,只是忽略它们。仅仅因为有人发表了评论,这并不意味着你必须自动回应它。如果你不这样做,他们就不会跟进了。
如果他们这样做,并且如果他们继续坚持更改(假设他们有能力坚持),您可以与他们进行私人谈话,以澄清他们认为的阻塞问题是什么。
这是纯粹的风格问题,还是掩盖了一些他们没有充分解释的更重要的东西?你有权礼貌地问他们,如果他们有什么不能接受的。
树立榜样
在你的职业生涯中,我们希望这将是一个漫长而成功的职业生涯,你会发现,理解人和人际关系是一项比简历上任何技术性缩写更有价值的技能。协作是一项棘手的业务,唯一比开发软件更难的是作为一个团队开发软件。
当你以善意、体贴和尊重的态度对待周围的人时,你将以最好的方式教会他们代码审查的温和艺术:举个例子。我觉得不错。