google 如何进行代码审查02

原文
https://google.github.io/eng-practices/review/reviewer/looking-for.html
What to look for in a code review (程式审核过程中要看些什么?)
在考虑以下要点时,请务必连同The Standard of Code Review一起考虑。
Design (设计)
程式审核里最重要的一环是CL 的整体设计

CL 内多个程式片段的改动之间的交互作用是否合理? 改动是属于程式库(codebase) 还是函式库(library)? 此次改动是否能和系统其他部分很好地整合? 现在是加入该功能的适当时机吗?

Functionality (功能性)
CL是否真的有符合开发者意图?开发者的意图对于使用者们是好的吗?这里使用者通常系指終端使用者 (受到改動而影響)与開發者(未來會用到該程式的人)双方。

在大多数情况,我们会期望开发者彻底测试他们的CL,并期望在接受审核时它能够正常运作。但身为审核者你仍必须去思考可能的「极端案例(edge cases)」、找出「并发问题(concurrency problem)」、 尝试「作为一个使用者去思考」,并且确保「在单纯阅读程式码时没有明显的程式缺陷(bug)」。

愿意的话你也可以去亲自去验证CL - 如果当改动会带来直面使用者的影响(user-facing impact) 时,比方说UI 改动,验证CL 的变化便会是审核者在整个过程中最重要的事情。单纯阅读程式码有时很难体会它会如何影响使用者,面对如此的改动如果觉得不方便自己测试的话,可以要求开发者展示(demo) 此次改动的功能性。

另外,审核功能性时格外重要的一点是,要注意CL 中是否有「平行程式设计(parallel programming)」的存在,并是否在理论上会造成deadlocks 或race conditions。这类的问题较难透过执行程式来查觉,通常会需要有人(开发者跟审核者) 一起仔细思考,确保该问题不会被引入程式库内。

Note: 这也是不使用可能会造成deadlocks 或race conditions 的并发模型(concurrency model) 很好的理由- 它可能会让程式审核或理解上造成困难。

Complexity (复杂性)
一个CL 是否复杂到超过原本所必须的? 针对任何层级的CL 请务必确认这几点- 单行程式是否过于复杂? 函式是否过于复杂? Class 是否过于复杂?

「复杂」通常代表着该程式很难快速被阅读程式的人所理解

也意味着很有可能其他开发者在呼叫或修改这段程式时引入缺陷

其中就是一种复杂性便是「過度設計 (Over-engineering)」,开发者会让程式过度通用化(more generic)超过它原本所需的,或是新增现在系统不需要用到的功能[1]。审核者对于必须非常警惕过度设计的发生。

鼓励开发者解决他们現在需要解决的问题,而非那些猜测未来可能会需要被解决的问题

可以在真正面临到那些未来的问题时才解决它们,因届时你才能更清晰看到问题的样貌(actual shape) 与需求。

[1] 个人认为和Donald Knuth 说得「过早最佳化是万恶的根源(Premature optimization is the root of all evil)」有类似意思。自己在开发过程中也常常落入相同窠臼,认为未来可能会需要所以现在先写起来放。但更常见的状况是,当实际面临问题时,状况可能和原先大相径庭导致需要重写。
Tests (测试)
请将要求单元、整合、端到端测试视为要求CL所做的适当变更。一般CL内除production code以外,测试也应该要被加入其中。除非该CL是为了处理某个紧急事件而存在。

另外,也要确保测试是「正确(correct)」、「合理(sensible)」、「有用的(useful)」。测试并非来测试他们自己本身,一般也极少为了测试写测试(write tests for tests),因此我们必须确保测试是有效的。

当程式真的出问题时,测试是否真的会失败? 如果被测试的程式发生改动时,测试是否会产生误报(false positives)? 每个测试是否有做出简单而有用的断言(assertions)?不同测试方法之间的测试是否适当分开?

请记住,测试也是必须维护的程式。不要因为它们不包含在main binary 内,

而接受测试程式中包含不必要的复杂性。

Naming (命名)
开发者是否为每个东西挑选了恰当的名字? [1]

一个好的命名意谓着

长到足以完整表达该东西的作用或做什么

同时不要长的难以阅读。

[1]推荐参考Clean code 101 — Meaningful names and functions
Comments (注释)
开发者是否用可理解的英文留下清晰的注释? 这些注释是否真的必要?

通常注释在解释为什么(explain why)这段程式存在(code exists)时相当有用,而不应该去解释某段程式正在做什么(not be explaining what some code is doing)。如果程式码本身不能清楚解释自己的话,意味着它需要更加简化(made simpler)。当然也有例外状况,比如解释正規表達式[1]或複雜的演算法正在做什么的注释往往相当有用,但对于大部分注释来说是用来说明那些不包含在程式本身的资讯,比方说为什么决定这样做背后的理由[ 2]。

查看该CL 之前的注释也很有帮助。或许有个TODO 项目现在可以移除、一个评论建议为什么不要进行这种改变等等。

要注意的是,注释与class、模组(module)、函式(function) 的文件不同。后三者要能够表达一段程式的目的、如何使用它、以及它在使用时的行为。

[1]请见先前关于Cloudflare全球大断线的文章
[2]常见的状况是基于商業上決定,而非程式面因素
Style (风格)
Google对于主要语言皆有提供风格指南,甚至包括大多数的冷门语言,因此请确保CL遵循适当的指南上的说明。

如果你想改进CL中某些不包含在风格指南中的风格要点时,请在评论前加上Nit:让开发人员知道这是你认为可以改善程式的小问题且并非强制性的。但记住,不要仅根据个人风格偏好阻止提交CL。

开发者不應在 CL 內同時包含主要風格的改動與其他程式的更改[1],这样会导致难以看出CL到底做出什么改动。同时也会让合并(merge)和回滚(rollback)更为复杂,并产生其他问题。例如,如果作者想要重新格式化(reformat)整个档案的话,让他们将重新格式拆成一个CL,然后再发送另一个包含功能修改的CL [2]。

[1] 比方说CL 内包含上百个更改缩排的文件,中间额外穿插程式的异动
[2]通常revert时会希望commit越小越好,如此能更易于回滚,请参考Atomic Commits with Git
Documentation (文件)
如果CL 更改用户如何「构建(build)」、「测试」、「交互(interact)」、「发布」程式的方法时,请检查是否也同时更新相关文档, 包括READMEs,g3doc 页面和其他生成(generated ) 的参考文件。如果CL 删除或弃用(deprecate) 程式,请考虑是否应该删除对应文档,如果缺少文档时请询问。

Every Line (每一行程式)
仔细查看你被分配审核的CL 的每一行程式

有些东西,比如资料文件(data files)、生成的程式(generated code)、大型资料结构(large data structures),你可以稍微扫过。 千萬不要在掃過開發者寫的 class、函式、程式區塊 (block of code) 時,並假設其內部的內容是沒問題的。 很显然的某些程式需要比其他程式更仔细的审查(scrutiny) -这是必须由你做出的判断(judgment call)。但至少你应该确定你理解所有程式在做些什么。

如果阅读程式过于复杂并且减慢审核速度时,那么你再继续审核前要让开发者知道这件事,并等待他们为程式做出解释、澄清(clarify)。在Google 我们聘请许多优秀的软体工程师,而你也是其中的一员。如果连你也无法理解程式的话,很可能其他人也不会。因此,你要求开发者去澄清此程式时,同时也在帮助未来的开发人员理解这些它们。

如果你能够理解程式但觉得没有资格进行某部份的审核,请确保CL 审核者中有一个适合(合格) 的审核人来审核该部分。尤其是针对「安全性(security)」、 「并发性(concurrency)」、「可访问性(accessibility)」、「国际化(internationalization)」等复杂问题时。

Context (前后文)
在充足的前后文(broad context) 下查看CL 通常很有帮助。

一般来说,程式码审查工具只会显示修改部分周围的几行程式而已。但有时你必须查看整个文件以确保改动是否合理。比方说,你可能只看到添加4 行新程式码,但实际上查看整个文件时会发现这4 行是被加在有50 行的函式里,此时便需要将它拆解为更小的函式。

以整个系统的角度出发来思考CL也是很有用的。该CL是否改善整体系统的程式品质,亦或是会让整个系统更加复杂?是否缺少测试? 千萬不要接受會降低整體系統程式品質運行狀況的 CL。因为大多数系统是由于许多小改动的积累而变得复杂,因此阻止新的改动引入复杂性(尽管很小)也非常重要。

Good Things (好事、优点)
当你在CL 里看到优点时记得告诉开发者,尤其是当他们用很棒的方式来解决你的评论时。

程式审查通常只关注在错误,但它们也应该同时应该为良好实践(good practices)提供鼓励与欣赏。这点在指导(mentoring)开发者时尤其重要: 比告訴告訴他們做錯了什麼,更好的是告訴他們做對什麼[1]。

[1] 个人认为并非不要指出错误,而是「多以鼓励来代替指出错误」,让其他开发者更有动力想将事情做好。其实透过简单的一句话让对方知道哪里做得很好,未来他们会将继续保持下去,并为其他开发者带来的正面影响
good-thing

对方注明每个commit 修改什么,可以帮助审核者快速进入状况

compliment
此时就不要吝于给出你的称赞吧!

Summary (总结)
在进行程式审核时,请务必确保

程式经过完善的设计
功能性对于使用者们是好的
对于任何UI 改动要合理且合眼(look good)
任何平行程式设计(parallel programming) 的实现是安全
程式不应该复杂超过原本所必须的
开发者不该实现一个现在不用而未来可能(might) 需要的功能
程式有适当的单元测试
测试经过完善的设计
开发者对于每样东西有使用清晰、明了的命名
注释要清楚且有用,并只用来解释「为什么存在(why)」而非「做什么(what)」
程式有适当的写下文件(一般在g3doc)
程式符合风格指南
确保你查看被要求审核的每一行程式码、确认上下文 (context)、确保你正在改善程式品質,并赞扬开发人员所做的好事与优点吧!

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值