本文译自Google最新开放的code review指南:How to do a code review
原文地址:https://google.github.io/eng-practices/review/reviewer/
该文档一共分为如下六篇:
一、 Code review的标准
Code review 的主要目的是确保Google代码库的整体代码运行状况随着时间的推移而得到改善。Code review的所有工具和流程都是为此而设计的。
为了实现这一目标,必须综合考虑许多因素,并做出取舍和平衡。
首先,开发人员必须能够在任务上取得进展。如果你从不向代码库提交改进后的代码,那么代码库就永远不会得到改进。另外,如果一个reviewer使任何更改都很难进行,那么开发人员就不愿意在将来进行改进。
另一方面,reviewer有责任确保每个CL(Change Log)具有这样的质量,即随着时间的推移,其代码库的整体代码健康状况不会降低。这可能很棘手,因为代码库通常会随着时间的推移而降低代码运行状况,特别是当团队的交付受到严重的时间限制,并且他们觉得必须采取捷径才能实现目标时。
此外,reviewer对他们正在审核的代码拥有所有权和责任。他们希望确保代码库保持一致,可维护以及“code review中要注意的内容”中提到的所有其他内容。
因此,我们将以下规则作为我们在code review中期望的标准:
一般来说,如果一个 CL并不完美,但是它肯定会提高当前系统的代码整体健康度,那reviewer就应该让它通过。
这是所有code review指南中的首要原则。
当然,这是有局限性的。例如,如果一个CL添加了一个reviewer不希望在其系统中使用的功能,即使代码设计得很好,reviewer也可以拒绝批准该CL。
这里的一个关键点是,没有“完美”的代码,只有更好的代码。Reviewer不应该要求开发人员对CL的每一个微小的部分进行打磨。相反,reviewer应该在项目的进展和reviewer的改进建议两者之间做好权衡。Reviewer不应该追求完美,而应该追求持续的改进。作为一个整体,提高系统可维护性、可读性和可理解性的CL不应该因为它不是“完美的”而延迟几天或几周通过审批。
如果有些东西可以做得更好,reviewer 应该随时留下评论。但是如果该评论所建议的改进不是很重要,可以在前面加上“Nit:”这样的前缀,让作者知道这种改进只是一种锦上添花的效果,作者可以选择忽略。
注意:本文档中没有任何内容推荐合入会明显恶化系统的整体代码健康状况的CL。只有在紧急情况下你才会那样做。
指导思想
Code review的一个重要功能是教授开发人员关于语言、框架或一般软件设计原则的新知识。留下帮助开发人员学习新东西的评论总是好的。随着时间的推移,共享知识是改善系统代码健康状况的一部分。请记住,如果您的评论纯粹是教育性的,但对于满足本文档中描述的标准并不是至关重要的,那么在它前面加上“Nit:”,或者以其他方式表明并不强制作者在本CL中解决它。
原则
技术事实和数据优先于意见和个人偏好。
在风格问题上,以风格指南为准则。任何风格指南中没有规定的纯样式点(空格等)都是个人偏好的问题。这些点原则上应该与现有的风格保持一致。但是如果这些点现在还没有形成一定的风格,那reviewer应该接受作者的风格。
软件设计的各个方面几乎从来不是纯粹的风格问题,也不只是个人偏好。它们是建立在基本原则的基础上的,应该在这些原则的基础上加以衡量,而不仅仅是只考虑个人意见。有时,如果作者能够证明(通过数据或基于可靠的工程原理)几种方法是同样有效的,那么reviewer应该接受作者的偏好。否则,reviewer的选择取决于软件设计的标准原则。
如果没有其他规则适用,那么reviewer可能会要求作者与当前代码库中的内容保持一致,只要这不会恶化系统的整体代码健康状况。
解决冲突
在对代码评审的任何冲突中,开发人员和reviewer应该始终根据本文档的内容以及“CL Author 's Guide“和“Reviewer Guide”中的其他文档,尝试达成一致意见。
当达成一致意见变得特别困难时,在reviewer和作者之间进行面对面的会议或VC(译者注:不知道是什么的缩写)将会有所帮助,而不是仅仅试图通过code revier评论来解决冲突。(不过,如果您这样做了,请确保将讨论结果记录在CL的评论中,以供将来的读者参考。)
如果这不能解决问题,最常见的解决方法就是升级。升级路径通常是更广泛的团队讨论,让TL参与进来,请求代码维护人员作出决策,或者请求Eng经理提供帮助。不要因为作者和审稿人不能达成一致意见而让CL无所事事。
二、 Code review关注点
注意:在考虑这些要点时,请务必同时参考“Code review的标准”。
设计
Code review 评论最重要的内容是CL的总体设计。CL中不同代码段之间的交互有意义吗?这个更改属于您的代码库,还是属于库?它与系统的其他部分集成得好吗?现在是添加此功能的恰当时机吗?
功能
这个CL是否达到了开发人员的目的?开发人员的意图对这段代码的用户有好处吗?“用户”通常是终端用户(当他们受到更改的影响时)和开发人员(将来必须“使用”这些代码)。
大多数情况下,我们希望开发人员能够很好地测试CLs,以便在进行codereview时代码能够正确地工作。然而,作为reviewer,您仍然应该考虑一些边界情况,寻找并发性问题,尝试像用户一样思考问题,并确保不会看到仅通过阅读代码就能发现的错误。
如果您愿意,您可以对CL进行验证—检查CL行为最重要的时间是当它具有面向用户的影响时,例如UI更改。当您仅仅阅读代码时,很难理解一些更改将如何影响用户。对于这样的更改,如果不方便在CL中进行修补并亲自尝试,您可以让开发人员提供功能的演示。
在代码评审过程中考虑功能的另一个特别重要的时刻是,在CL中是否存在某种并发编程,这理论上可能会导致死锁或竞争条件。仅通过运行代码很难发现这类问题,通常需要有人(开发人员和review)仔细考虑这些问题,以确保没有引入问题。(注意,这也是一个不使用可能存在竞争条件或死锁的并发模型的好理由——这会使code review或理解代码变得非常复杂。)
复杂性
CL比它应该的复杂吗?在cl的每一层检查这个—单个行是不是太复杂了?函数是否过于复杂?类太复杂了吗?“太复杂”通常意味着“代码读者不能很快理解”。这也意味着“当开发人员试图调用或修改这段代码时,他们很可能会引入bug。”
一种特殊类型的复杂性是过度设计,开发人员使代码比需要的更通用,或者增加了系统目前不需要的功能。reviewer应该特别警惕过度设计。鼓励开发人员解决他们知道现在需要解决的问题,而不是解决开发人员推测将来可能需要解决的问题。未来的问题应该在它到来后解决,你可以看到它在物理宇宙中的实际形状和需求。
测试
根据更改要求进行单元测试、集成测试或端到端测试。一般来说,测试应该添加到与生产代码相同的CL中,除非CL正在处理紧急情况。
确保CL中的测试是正确的、合理的和有用的。测试本身不进行测试,而且我们很少为我们的测试编写测试—人类必须确保测试是有效的。
当代码有问题时,测试会真的失败吗?如果下面的代码发生变化,它们会开始产生假阳性吗?每个测试都做出简单而有用的断言吗?测试是否在不同的测试方法之间适当地分开?
请记住,测试也是必须维护的代码。不要仅仅因为测试不是主分支的一部分就接受测试中的复杂性。
命名
开发人员是否为所有东西都选择了好名字?一个好的名字应该足够长,从而可以充分地表达条目是什么或做了什么,并且不会长到让人难以阅读。
注释
开发人员是否用可理解的英语编写了清晰的注释?所有的评论都是必要的吗?通常,注释在解释某些代码为什么存在时很有用,而不应该解释某些代码在做什么。如果代码不够清晰,无法达到自解释,那么应该简化代码。也有一些例外(例如,解释正则表达式和复杂算法在做什么通常帮助很大),但大多数注释是针对代码本身不可能包含的信息,比如决策背后的推理。
查看CL之前的评论也会很有帮助。也许现在有一个可以删除的待办事项,一个建议不要做这个更改的评论,等等。
注意,注释不同于类、模块或函数的文档,这些文档应该表示代码的用途、应该如何使用以及使用时的行为。
风格
我们为Google提供所有主要语言的风格指南,甚至包括大多数小众语言。确保CL遵循适当的样式指南。
如果你想改进样式指南中没有涉及的一些样式点,请在评论前加上“Nit:”,让开发人员知道你认为这会改善代码,但不是强制性的。不要仅根据个人风格偏好阻止提交CL。
CL的作者不应将大量样式更改和代码更改放在一起提交。它使得很难看到CL中的代码更改,使合并和回滚更复杂,并导致其他问题。例如,如果作者想要重新格式化整个文件,让他们只将重新格式化为一个CL,然后再发送另一个CL及其功能更改。
文档
如果CL更改了用户构建、测试、交互或发布代码的方式,请检查它是否还更新了相关文档,包括READMEs、g3doc页面和任何生成的参考文档。如果CL删除或弃用代码,请考虑是否也应该删除文档。如果缺少文档,就去问作者要。
每一行
查看分配给您的每一行代码。有些东西,比如数据文件、生成的代码或大型数据结构,您有时可以大致浏览一下,但是由人编写的类、函数或代码块不能粗略的浏览,并假定其中的内容是正确的。显然,有些代码需要比其他代码检查的更仔细—这是您必须做出的判断—但是您至少应该确保您理解所有代码在做什么。
如果这段代码您阅读起来比较费劲,并且会减慢评审的速度,那么您应该让开发人员知道这一点,并在您尝试评审之前等待他们澄清它。在谷歌,我们雇佣优秀的软件工程师,你就是其中之一。如果您不能理解代码,其他开发人员也很可能无法理解。因此,当您要求开发人员澄清这些代码时,您也在帮助未来的开发人员理解这些代码。
如果您理解所review的代码,但是您觉得不能胜任这次review,那么请确保针对这个CL有一个合格的review,特别是对于复杂的问题,比如安全性、并发性、可访问性、国际化等等。
上下文
在广泛的上下文中查看CL通常是有帮助的。一般地,code review工具只会显示正在更改的部分周围的几行代码。有时您必须查看整个文件,以确保更改实际上是有意义的。例如,您可能只看到添加了四行,但是当您查看整个文件时,您会看到这四行位于一个50行方法中,现在确实需要将其分解为更小的方法。
在整个系统的上下文中考虑CL也很有用。这个CL是提高了系统的代码健康度,还是使整个系统更复杂、测试更少等等?不要接受降低系统代码健康度的CLs。大多数系统都是通过许多累积起来的小更改而变得复杂的,因此,即使是防止在新更改中引入很小的复杂性也是很重要的。
处理CL中好的方面
如果您在CL中看到一些不错的东西,请告诉开发人员,特别是当他们以一种很好的方式处理您的一条评论的改进建议。Code review通常只关注错误,但是它们也应该为好的实践提供鼓励和赞赏。有时候,在指导方面,告诉开发人员他们做对了什么比告诉他们他们做错了什么更有价值。
总结
在code review过程中你应确保:
代码设计得很好。
该功能对代码的用户(开发人员以及系统的用户)有益。
任何UI更改都是合理的,看起来也不错。
任何并发编程都是安全的。
代码并不比它需要的复杂。
开发人员没有实现他们将来可能需要但不知道现在是否需要的东西。
代码有适当的单元测试。
单元测试是精心设计过的。
开发人员在代码中的所有命名都是清晰的。
注释清晰有用,主要解释为什么而不是解释是什么。
代码被合适地文档化了(通常在g3doc中)。
代码符合我们的样式指南。
确保检查您被要求检查的每一行代码,查看上下文,确保您正在改进代码的健康状况,并赞扬开发人员做的好的地方。
三、 CL阅读指南
摘要
既然您知道“Code review关注点”,那么管理跨多个文件的codereview的最有效方法是什么?
这种变化有意义吗? CL(change log)的描述清晰明了吗?
首先看看CL中最重要的部分。CL的整体设计好吗?
按照适当的顺序查看CL的其余部分。
第一步:从全局的视角看下CL
看看CL的描述,以及CL大概做了什么。CL涉及的变更有意义吗?如果这个变更一开始就不应该发生,请立即回复并解释为什么不应该发生变更。当您拒绝这样的变更时,最好也向开发人员建议他们应该做什么。
例如,你可以说“看起来你在这方面做得不错,谢谢!”不过,我们实际上准备删除你在修改的FooWidget系统,所以我们现在不想对它做任何新的修改。你不如来重构我们的新BarWidget类?”
注意,review不仅要在拒绝了当前的CL时提供一个替代的建议,而且很有礼貌的拒绝。这种礼貌是很重要的,因为我们想要表现出即使我们意见不一致,我们作为开发人员也彼此尊重。
如果您发现出现多个你不希望进行更改的CLs,那么您应该重新考虑一下团队的开发流程或外部贡献者发布的流程,以便在他们编写CLs之前跟你有更多的沟通。最好在人们完成大量工作之前就说“不”,这些工作现在必须扔掉或彻底重写。
第二步:检查CL的主要部分
找出这个CL的“主要”部分,CL的主要部分一般是一个或者几个文件。通常,只有一个文件具有最多的逻辑更改,它是CL的主要部分。首先看看这些主要部分。这有助于为CL的所有较小部分提供上下文,并且通常这会加速代码评审。如果CL太大,您无法确定哪些部分是主要部分,请询问开发人员应该首先查看什么,或者让他们将CL分割成多个CLs。
如果您看到CL的这一部分存在一些主要的设计问题,您应该立即给出反馈,即使您现在没有时间来检查CL的其余部分。事实上,检查CL的其余部分可能是浪费时间,因为如果设计问题足够严重,那么许多其他正在检查的代码后面可能会删掉或者重构,不管怎样都无关紧要。
如果主要设计有缺陷,立即给出反馈非常重要,有两个主要原因:
开发人员通常会提交一个CL,然后在等待评审时立即基于该CL开始新的工作。如果您正在检查的CL中存在主要的设计问题,那么他们还必须重新编写后面的CL。您应该在它们在有问题的设计上做过多额外工作之前阻止它们。
大的设计变更比小的变更需要更长的时间。开发人员的任务几乎都有截止日期;为了在代码库中保持高质量代码的同时在这些截止日期前完成任务,开发人员需要尽快开始对CL主要问题进行修改。
第三步:以适当的顺序查看CL的其余部分
一旦你确认整个CL没有重大的设计问题,试着找出一个逻辑序列来查看这些文件,同时确保你不会漏看任何文件。通常在查看主要文件之后,最简单的方法是按照代码审查工具向您提供的顺序浏览每个文件。有时在阅读主代码之前先阅读测试也很有帮助,因为这样你就可以了解CL做了什么。
四、 Code review 的速度
为什么code review 要快?
在谷歌中,我们针对开发团队共同开发产品的速度进行优化,而不是针对单个开发人员编写代码的速度进行优化。个人发展的速度很重要,但是没有整个团队的速度重要。
当code review很慢时,会发生以下几件事:
整个团队的速度降低了。如果一个人对评审的反应不是很快,他虽然在这期间做了一些其他的工作,但是,由于每个CL都要等待一次又一次的评审,团队其他成员的新特性和bug修复会延迟几天、几周或几个月。
开发人员开始抗议code review过程。如果reviewer每隔几天才回复一次,但每次都要求对CL进行重大更改,这对开发人员来说可能是令人沮丧和困难的。通常,这表现为对reviewer的“严格”的抱怨。如果reviewer请求相同的实质性更改(这些更改确实改善了代码的健康状况),但是每次开发人员进行更新时都会快速响应,那么抱怨就会消失。对代码评审过程的大多数抱怨实际上是通过加快过程来解决的。
代码健康状况会受到影响。当评审速度较慢时,允许开发人员提交不如预期的CLs的压力就会增加。缓慢的评审还会阻碍代码清理、重构和对现有CLs的进一步改进。
代码评审应该有多快?
如果您没有集中精力完成任务,那么应该在任务完成后不久进行代码检查。
一个工作日是响应代码审查请求所需的最长时间(即第二天早上的第一件事)。
遵循这些指导原则意味着一个典型的CL应该在一天内(如果需要的话)进行多轮评审。
速度与中断
有一段时间,对个人速度的考虑超过了对团队速度的考虑。如果你正在集中精力做一项任务,比如写代码,不要打断自己去做codereview。研究表明,开发人员在中断开发之后,可能需要很长时间才能恢复到平稳的开发流程。因此,对团队来说,在编写代码时打断自己实际上比让另一个开发人员等待code review的时间更昂贵。
相反,在你的工作中等待一个断点,然后你才回应一个审查的请求。这可能是当你当前的编码任务完成时,午饭后,从会议回来,从微型厨房回来,等等。
快速反应
当我们讨论代码评审的速度时,我们关心的是响应时间,而不是CL完成整个评审并提交所需的时间。理想情况下,整个过程也应该是快速的,但是对于单个响应的快速响应比整个过程的快速响应更重要。
即使有时需要很长时间才能完成整个评审过程,但是在整个过程中reviewer的快速响应可以极大地减轻开发人员对“缓慢”code review的沮丧。
如果在一个CL提交过来时,你太忙了,难以做一个完整的review,你仍然可以发送一个快速反应,让开发人员知道什么时候你会开始review,建议由其他reviewer来评审可以更快地响应的效果,或者提供一些最初的粗略评论。(注意:这并不意味着您应该中断编码,即使是为了发送这样的响应—也应该在您工作中的一个合理的断点发送响应。)
重要的是reviewer要花足够的时间进行评审,以确保他们的“LGTM”的意思是“这段代码符合我们的标准”。然而,个人的反应最好还是要快。
跨时区评论
当处理时区差异时,试着在作者还在办公室的时候给出回应。如果他们已经回家了,那么在他们第二天回到办公室之前,确保你的评估已经完成。
LGTM评论
为了加快code review的速度,在某些情况下,reviewer应该给出LGTM/Approval,即使他们还在CL上留下未解决的注释。这是在以下两种情况下完成的:
reviewer确信开发人员将适当地处理reviewer剩余的所有评论。
其余的更改是次要的,开发人员不一定非要完成。
如果不清楚,reviewer应该指定他们想要的选项。
当开发人员和reviewer处于不同的时区时,使用带有注释的LGTM尤其值得考虑,否则开发人员将会等待一整天,只为获得“LGTM,批准”。
大型CLs
如果有人给你提交了一个非常大的CL,你不知道什么时候你能有时间去review它,你的典型的反应应该要求开发人员把CL分割成几个较小的CLs,而不是一个巨大的CL必须一次性审查。这通常是可行的,并且对reviewer非常有帮助,即使这需要开发人员做额外的工作。
如果CL无法分解为较小的CL,并且您没有时间快速查看整个内容,那么至少要对CL的整体设计写一些评论并将其发送回开发人员以进行改进。作为reviewer,您的目标之一应该是始终取消阻止开发人员或使他们能够快速采取某种进一步的操作,而不会牺牲代码运行状况。
Code review随时间的改进
如果您遵循这些指导原则,并且对code review非常严格,那么您应该会发现,随着时间的推移,整个code review过程会变得越来越快。开发人员了解健康代码需要什么,并从一开始就向您发送非常棒的CLs,这使得需要的评审时间越来越少。reviewer学会快速响应,而不是在评审过程中添加不必要的延迟。但是不要为了提高速度而牺牲code review标准或质量——从长远来看,这实际上不会使任何事情发生得更快。
紧急情况
在一些紧急情况下,CLs必须非常快速地通过整个评审过程,并且不会严格按照质量指南来要求它。但是,请看看什么是紧急情况?用于描述哪些情况实际上符合紧急情况,哪些不符合紧急情况。
五、 如何编写code review 评语
摘要
对人友善
解释你的观点
在给出明确的指示与指出问题并让开发人员决定之间保持平衡。
鼓励开发人员简化代码或添加代码注释,而不仅仅是向您解释复杂性
礼貌
一般来说,礼貌和尊重是很重要的。并且您也要对review对象非常明了和有帮助。一种方法是确保您总是对代码进行评论,而从不对开发人员进行评论(译者注:对事不对人)。你不必总是遵循这个习惯,但是当你说一些可能会让人心烦意乱或有争议的话时,你绝对应该使用这个习惯。例如:
反例:“为什么您在这里使用线程,但是没有从并发中获得任何好处?”
正例:“这里的并发模型增加了系统的复杂性,但我看不到任何实际的性能优势。因为没有性能上的好处,所以这段代码最好是单线程的,而不是使用多线程。”
解释为什么
关于上面的正面示例,您将注意到的一件事是,它帮助开发人员理解您为什么要发表评论。您并不总是需要在评审注释中包含这些信息,但是有时候,对于您的意图、您所遵循的最佳实践,或者您的建议如何改进代码健康状况,给出更多的解释是合适的。
提供指导
一般来说,修复CL是开发人员的责任,而不是review的责任。您不需要为开发人员提供解决方案的详细设计或编写代码。
不过,这并不意味着review应该毫无帮助。一般来说,你应该在指出问题和提供直接指导之间取得适当的平衡。指出问题并让开发人员做出决策通常有助于开发人员学习,并使code review变得更容易。它还可以产生更好的解决方案,因为开发人员比reviewer更接近代码。
但是,有时直接的指令,建议甚至代码会更有帮助。Code review的主要目标是获得最佳的CL。第二个目标是提高开发人员的技能,以便他们随着时间的流逝需要越来越少的审查。
接受解释
如果您要求开发人员解释一段您不理解的代码,这通常会帮助他们更清楚地重写代码。偶尔,在代码中添加注释也是一种适当的响应,只要它不只是解释过于复杂的代码。
仅在code review工具中编写的解释对将来的代码读者没有帮助。它们只在少数情况下是可接受的,例如当您正在review一个您不太熟悉的区域,并且开发人员仅仅解释了一些代码的显而易见的内容时。
六、 处理回退
有时开发人员会抵制code review。要么他们不同意你的建议,要么他们会抱怨你总体上过于严格。
谁是对的?
当开发人员不同意您的建议时,请先花点时间考虑一下它们是否正确。 通常,开发人员比您更接近代码,因此可能实际上他们对代码的某些方面比您更了解一些。 他们的论点有意义吗? 从代码健康角度来看,这有意义吗? 如果是这样,请让他们知道他们是对的,然后解决问题。
然而,开发人员并不总是正确的。在这种情况下,reviewer应该进一步解释为什么他们认为他们的建议是正确的。一个好的解释不仅说明了对开发人员的回答的理解,也说明了为什么开发人员需要做出更改的附加信息。
特别是,当reviewer认为他们的建议将改善代码的健康状况时,如果他们认为所产生的代码质量改进能够证明所要求的额外工作是合理的,那么他们应该继续提倡更改。改善代码健康状况往往是一些小步骤。
有时候,为了让开发人员真正理解您的一个建议之前,您需要花几轮时间来解释它。您只要确保始终保持礼貌,并让开发人员知道您听到了他们在说什么,您只是不同意。
令开发人员不安
reviewer有时认为,如果自己坚持要进行改进,开发人员会感到不安。有时候开发人员确实会感到沮丧,但是这通常是很短暂的,之后他们会非常感谢您帮助他们提高了代码的质量。通常,如果您在评论中表现得很有礼貌,开发人员实际上一点也不会感到不安,而这种担心只存在于您的脑海中。通常,令人不安的地方更多的是评论的编写方式,而不是reviewer对代码质量的坚持。
稍后清理
回退的一个常见原因是开发人员(可以理解)想要完成任务。 他们不想仅仅为了获得此CL而进行另一轮审核。因此,他们说他们将在以后的CL中清除某些内容,因此您现在应该LGTM此CL。 一些开发人员对此非常好,并会立即编写后续的CL来解决此问题。 但是,经验表明,开发人员在编写原始CL之后花费的时间越多,清理工作的可能性就越小。 实际上,通常除非开发人员在当前CL之后立即进行清理,否则它永远不会发生。 这不是因为开发人员不负责任,而是因为他们有很多工作要做,而清理工作却在其他工作中被遗忘或遗忘。 因此,通常最好是坚持要求开发人员在代码进入代码库并“完成”之前立即清理其CL。让人们“稍后清理”是代码库退化的一种常见方法。
如果CL引入了新的复杂性,在提交之前必须清理它,除非是紧急情况。如果CL暴露了周围的问题,而这些问题现在还无法解决,开发人员应该为清理工作提交一个bug文件,并将其分配给自己,这样它就不会丢失。他们还可以选择在引用已归档错误的代码中编写TODO注释。
对严格的普遍抱怨
如果您以前有相当松散的代码评审,而现在您转而进行严格的评审,那么一些开发人员将会非常大声地抱怨。提高代码评审的速度通常会使这些抱怨逐渐消失。
有时,这些抱怨可能要花费数月的时间才能消失,但是最终,开发人员往往会看到严格的代码审查的价值,因为他们会看到自己帮助生成的出色代码。 有时,一旦发生某种事情,使严格的抗议者甚至成为您最坚强的支持者,这会使他们真正地看到自己在增加的价值。
解决冲突
如果您遵循上述所有方法,但是您仍然遇到您自己和开发人员之间无法解决的冲突,请参阅代码评审标准,了解有助于解决冲突的指导原则和原则。