代码审查是编写软件的重要组成部分,尤其是在团队合作时。 在团队中制定一个共识的代码审查礼仪非常重要。 代码审查是一种评论,评论往往比代码编写本身更具个人色彩。 粗心大意、未经充分研究或不敏感的代码评论会导致团队成员之间的困难,降低团队整体生产力,并随着时间的推移降低代码质量。 本文将简要定义代码审查,描述一些常见错误,并提供一些快速技巧,以改进代码审查流程。
什么是代码审查?
代码审查是共享代码以供其他工程师审查的过程。 代码审查可以在 结对编程 会话期间口头进行,或者通过审查 CodePen 和 GitHub 等网站上的代码进行。 主要而言,代码审查在像 GitHub 这样的工具中进行,当工程师提交 拉取请求 时。
评论非常有益。 召集工程师讨论代码可以确保他们达成一致,无论是在现场还是通过分享评论。 此外,审查可以帮助发现代码或注释中的小错误,例如拼写错误,并且可以帮助较新或更初级的程序员学习代码库。 如果做得好的话,定期代码审查对所有人都有益。
代码审查的常见目标是使代码更改尽可能少且清晰,以便审阅者可以轻松理解发生了哪些更改以及代码中发生了什么。 如果代码审查更小,它们会更频繁,可能每天几次,并且更易于管理。
审查代码应该是每个开发人员工作流程的一部分。 高级审阅者有机会进行指导/辅导,甚至偶尔从中学到一些新东西。 初级审阅者可以成长,并且经常通过他们提出的问题来帮助确保代码可读性。 事实上,初级工程师通常是确保代码可读性的最佳团队成员。
对于独自工作的工程师而言,可以向外部人员寻求反馈,例如在聚会、GitHub、开源 Slack 频道、Reddit、Twitter 等,可以使独自工作的程序员有机会参与代码审查流程。
如果我们都能就一个既定的代码审查流程和语言达成一致,那么维持一个积极的环境,以进行创造性和高效的工程将变得更加容易。 代码审查礼仪对每个人都有益,无论是在独自工作还是在团队中工作。
苛刻的代码审查会伤害感情
看到漏洞和问题不断出现,并且在心理上无法解决它们,这会导致失败感和抑郁情绪。 当审视目前的项目时,我只能看到负面因素。 我犯下的错误、错误命名和错误。 这导致我太沮丧而无法做出贡献,这又导致我因为没有做出贡献而感到沮丧。
– Tim Wood,Momentjs 的创造者
网上有很多评论、帖子和推文,由有影响力的工程师表达他们因代码审查而受伤的感受。 这并不直接意味着审阅者试图刻薄。 感到防御是面对评论或反馈时正常的,相当人性化的反应。 审阅者应该意识到他们的评论的语气、语调或情感如何被审阅者解读,请参阅 奥卡姆剃刀。
就像这些评论者没有把维护人员当人看一样,我们也会犯错误。 https://#/tBa8kzymU4
— Henry Zhu @SF (@left_pad) 2017年9月18日
虽然审查代码非常有益,但糟糕或马虎的审查可能产生相反的结果。 避免不提供背景的批评。 换句话说,花点时间解释为什么某件事错了,哪里错了,以及如何避免以后再犯同样的错误。 表达这种尊重审阅者的态度可以加强团队,提高工程意识,并帮助达成技术定义。
改善代码审查礼仪的快速技巧
代码本质上是逻辑性的。 就像很容易注意到拼写错误一样,很容易找出错误或可以改进的代码。 在审视和讨论逻辑事物(如代码)时,人的天性是无视他人的感受。 这会导致感情受伤,并失去对学习和协作的关注。
由于人的天性,改善代码审查礼仪很难! 以下是我所做、所言、所见或所收到的内容的快速清单,这些内容是代码审查礼仪艺术中的轻松胜利。
移除个人
工程师可能在不知不觉中忽略了深刻的批评与批评之间的区别,这是因为 沟通中的个人关系。
下面的几行分析了一个关于理论函数
的代码审查评论,建议有机会尽早从函数中返回。
你和我的: 使用你或我可能并非有意冒犯,所以不用担心。 然而,随着时间的推移,涉及个人可能会开始让人感觉不太积极,尤其是在加入了语调之后。
你应该尽早从该函数中返回
我们: 使用我们
具有包容性,并且是更直接地说出某件事而不让某人感到防御的可靠方式。 然而,如果说话者说我们
,并且根本没有参与代码开发,那么这似乎是虚假的包容性且不敏感的。
我们应该尽早从该函数中返回
不涉及个人: 不涉及个人,对话或审查将清楚地传达问题、想法或问题。
尽早从该函数中返回
请注意,在不使用个人代词的情况下传达同一内容所需文本的字数更少,并且清晰度更高。 这有助于人际互动,将代码讨论与个人讨论分开,并且用更少的词就可以传达相同的想法。
保持激情的对话安静
激情是改进的重要动力。 本质上是批判性的激情可以非常体贴和激励人心。 如果接受评论的人参与其中,那么本质上是批判性的反馈将是最有用的。 这种沟通在架构讨论或讨论新产品时经常出现。
如果接受评论的人参与其中,那么本质上是批判性的反馈将是最有用的。 注意: 接受信息的人必须参与到评论中。
想象一下,这条评论以夸张的身体动作、更激动的语调和更高的音量说出。
此模型中使用了 8 种网络字体,这可能会影响页面加载速度,甚至可能导致由新竞态条件引起的某些跟踪指标!
然后,想象一下类似的评论,甚至更简洁,但以平静的态度、更慢的速度和正常的音量说出,后面接着一个问题。
此模型中使用了 8 种网络字体。 这将影响页面加载速度,并且可能会导致由于潜在的竞态条件而导致的跟踪指标问题。 如何改进?
请注意,上面的评论几乎相同。 第二条评论甚至更直接。 它将问题陈述为一个事实,然后请求反馈。
在充满激情的时候,要记住的一件重要事情是使用更安静的语调。 这是一个身体上的决定,而不是社交决定。 激情的语言可以相同,但根据沟通者的语调方向,感知却截然不同。 如果身体语调(肢体语言)、语调、音调和音量保持温和,那么人们观察到,观众更有可能保持参与,即使评论本质上是批判性的。
如果语调具有攻击性(夸张的身体动作、更激动的语调、更高的音量),那么使用的实际词语可能很温和,但观众可能会感受到完全不同的东西。 这种沟通会导致尴尬、观众不参与,甚至失去尊重。
具有攻击性的沟通在充满激情的沟通中很常见,因为人的天性想要保护我们热爱的想法。 因此,如果您观察到您的观众在讨论您热爱的某些事情时没有参与,那么不要过于担心。 关键是要记住,如果您能够创造出感知上的温和沟通,那么您的观众将更容易保持参与,即使他们最初并不赞同。
不要审查作者,审查代码
在上面对话的基础上,无论是在书面交流还是实际肢体语言中,几乎在任何情况下,指点行为都不是最佳的沟通方式。它将对话的焦点从对话的语境转移到了人或事物上。
下面的回复提供了一条评论,然后是一个链接。在代码审查的语境下,评论的第二部分和链接将读者带离代码审查的语境,这令人困惑。
// Return out of this function earlier
// You need to learn about functional programming
下面的评论提供了一条评论,然后是一个伪代码建议。
/*
return early like this:
*/
const calculateStuff = (stuff) => {
if (noStuff) return
// calculate stuff
return calculatedStuff
}
在上面的两个例子中,第一个例子会导致读者远离问题。对话变得更加抽象,甚至存在主义。第二个例子直接指向问题,然后提供一个与评论直接相关的伪代码片段。
在审查代码时,最好只评论与上下文相关的项目。泛泛的评论会导致失去上下文。如果必须进行更广泛的讨论,则应在代码审查之外进行。这将使代码审查保持清晰,并限定在正在审查的代码范围内。
对错可以改变
开发人员几乎总是想重写代码。实时地将问题分解成任务以解决当前情况是自然而然的。但是,关注产品的历史谁和为什么对于概念化很重要,因为可以获得很好的上下文。“历史会重演”这句话在批判产品或被批判你编写的产品时要牢记。从历史背景中总能获得大量的知识。
JavaScript是在一周内制作出来的,被认为是一种粗陋的脚本语言,后来成为最 广泛 使用的编程语言。 可缩放矢量图形 (SVG) 在 1999 年得到支持,几乎被遗忘,现在它们继续流行,因为它们提供了新的机会。即使万维网(互联网)也是为了文档共享而设计的,当时人们并没有预料到如今的结果。在考虑软件和工程时,要记住所有这些技术——虽然逻辑和可预测的结果应该是目标,但成功往往来自于意想不到的结果!敞开心扉!
一些可以帮助代码审查礼仪的资源和工具
- Alexjs:一个由Titus Wormer开发的工具,用于捕捉不敏感、不体贴的写作。
- Grammarly:一个扩展程序,可以帮助改进浏览器中的沟通。
- Write Good:一个由Brian Ford开发的命令行工具和文本编辑器插件,可以帮助改进文本编辑器和 shell 中的沟通。
- Awesome Writing Tools:一个Awesome List,用于改进写作的工具。
结论
上面的列表包含了一些通用、高级的事项,可以帮助在谈论、审查或阅读代码时积极参与——代码审查礼仪。
我是一个伪君子。我犯了所有我在本文中建议不要犯的错误。我是一个人。我在这里的目标是帮助其他人避免我犯过的错误,并且可能鼓励一些审查代码的行为标准,以便工程师可以更公开地讨论代码,而不必担心被伤害或伤害他人。
很棒的文章——谢谢。这里有很多我同意的观点。在类似的主题上,我写了https://capgemini.github.io/learning/better-learning-code-reviews/——请看一看。
很棒的东西,Malcolm。
我真的很喜欢你的文章!我立刻就读了它,并很高兴更多的人在思考类似的事情。特别是对我来说,关于工具的部分让我点击了一些可能改善我的工作流程的东西。
感谢分享!
我使用的其他一些建议
1) 我进行代码审查是为了涵盖好、坏和丑。
2) 我会问自己:“如果我必须维护这段代码,我会想知道什么?”
3) 我会请其他人说出来,如果他们在我的算法或结构中看到了我做错的地方。
4) 我经常会提出备选实现方案,并说明其优缺点(例如,使用元数据和反射与命令式代码,使用 LINQ 与“旧式”编码)。
5) 而且最重要的是,我不主持其他人的代码审查,我会请他们自己主持对他们代码的审查。
#5 Marc 的想法很棒。
这太棒了。解释得很棒。根据我的经验,以下是一些补充。
代码审查可以基于团队了解的管理原则。否则,工程师很容易失去同步。
关注实质而不是风格帮助我提取了对方传递的信息。我通常首先假设评论的人是为了帮助我。
很多时候,代码审查仍然会导致很多争论。指派一个可信的人来解决分歧会有所帮助。很多时候,“我只想提交我的 PR”的情绪化过程,或没有基于团队原则的自我辩护会导致立即发生争论。如果指派一个人来解决 PR 中的问题,这个人一直被证明能够解决类似的问题,并且能够很好地解释他们的过程,那么感觉分歧会导致成员团结起来而不是分崩离析。
非常好的文章。不过我有一个问题。
在与团队合作并不断进行推送/PR 的情况下,审查每个拉取请求是否会很繁琐?你如何解决这个问题?
正如 Malcom 所说,很棒的文章!我已经与我的团队分享了它。
我评论只是为了让你知道我欣赏这篇文章,并重视分享那些不像最新科技闪光点那样“光鲜亮丽”的内容。
我发现与自己的家人合作,要保持冷静和客观难得多。但由于我曾经是许多不必要的个性化批评的承受者,所以我尽量小心,使自己对其他人的批评基于纯粹的逻辑。
这帮助我接受了其他人提出的我可能通常不想处理的解决方案,因为我学会了欣赏其他人只是把事情做完,如果他们想用 basecamp *叹气*,我们就会用 basecamp。这比糟糕的沟通和持续的错误要好。事实上,我真的很高兴为一个特定的客户使用 basecamp,因为从那个客户开始使用清晰的沟通的那一刻起,他们就开始使用清晰的沟通。具体来说,在电子邮件中是对话语气,但在项目管理软件中,对话风格没有意义。
所以现在我已经写出来了,我很好奇环境,甚至可能是评论表格(附有实际记录的要求)将如何影响用户的反馈。
我还没有做过,但我快要做一个自己的表格,专门用于评论。包括诸如“注意:确保你的评论中不要包含“我/我们/她”之类的内容。代码甚至可以用于强制某些字段不允许这些词语在其中出现。:) 专制?也许吧,但这肯定会传达关键信息,不要做混蛋。
我发现那些乐于与他人合作的人很容易遵守社会规则,而那些不愿意的人无论如何都会对被强迫行为感到愤怒。也许这是一个双赢局面。
我建议在这里添加一点,这与语气关系不大,而与内容关系更大:避免要求进行可整理的更改。
我见过太多人对代码进行审查时提出诸如“依赖项应该按字母顺序排序”、“这可以是一个三元运算符”、“使用制表符/空格而不是空格/制表符”之类的建议。使用代码 linter 在项目中强制执行这些规则可以让审查者更多地关注代码的意图,而不是结构。
非常棒的观点!感谢您有见地的补充。
糟糕。你写了一篇糟糕的文章。再去试试吧。
开玩笑的……我之前也经历过类似上面这样的代码审查,不过很遗憾。感谢这些很棒的建议!
这篇文章的方向是对的,但 IMO,你永远无法从团队代码审查中消除个人因素。
即使消除了指责性的语言,人类的天性也倾向于忽视代码中好的部分,而专注于做得不好的地方,要么是因为这个人不知道如何做得更好,要么是因为他们没有时间(通常是后者,因为大多数工程师如果有时间都会尝试深入研究)。
太多时候,即使是最善意的代码审查也会退化为团队中的“摇滚明星”告诉其他团队成员如何改进他们的代码。
这在团队中建立了等级制度,阻碍了团队合作。
Rock 可能开始感到沮丧,因为他总是给予别人他的知识,而他们似乎并不领情。
这也让大家在知道 Rock 会告诉他们如何用 C# 最新版本的最新功能做得更好时,变得不那么敢于提交代码。然后他们就开始反复检查东西,试图找出是否有更好的方法,这让他们变慢了,也巩固了 Rock 作为团队明星的地位,因为他(我从来没有遇到过女性 Rock)是团队中最快、最能干的人。
这总是以“它让代码库变得更好(不言而喻:人们只需要学会不要那么敏感)”为借口来辩解。
但最终,代码仍然是由人编写的。不幸的是,必须考虑他们的感受和需求。如果你不同意这个说法,请跟我重复一遍: _并非每个人都像我一样_
但我敢肯定,大多数软件团队中,“敏感”的人比 Rock 多。
这就是为什么我仍然反对代码审查,并且积极地避免那些在招聘广告中写着他们进行团队代码审查的公司。
在我的公司从来没有过代码审查,但原因与你不同,我的经验是,任何形式的批评都似乎会遇到同样的问题。
无论是设计、摄影、写作、编辑、编程等……无论是来自团队成员、程序员、员工、客户等……效果都是一样的。这就是我欣赏这个话题所带来的原因。
我不想被指责工作质量低劣,其他人也是一样,我也不希望客户对员工指手画脚,或者他们互相指手画脚。
你无法逃避反馈,代码审查似乎只是强迫性的批评。也许代码审查是否应该进行是一个全新的议题?
在审查中表达观察结果的另一种好方法是提出问题,例如
“我们可以……?”
“如果我们……?”
“如果我们……会起作用吗?”
这样做的一个好处是,你没有命令改变,而是参与到对话中。此外,与其断言自己拥有更高深的知识(尽管对语境的了解更少!),不如给原作者机会解释他们的理由,并开启关于替代方案的协作性对话。