代碼評審的主要目的是確保代碼庫的整體質(zhì)量隨時間推移逐步得到提升。這是一項艱巨的任務瞳腌,因為代碼庫整體質(zhì)量常常會隨著每次提交代碼質(zhì)量的小幅下降而退化绞铃。代碼評審就是確保每個CL(變更列表)的質(zhì)量,保證代碼庫整體質(zhì)量不會隨著時間的推移而下降嫂侍。
每個企業(yè)甚至每個團隊都有自己的code review方式儿捧,無所謂好壞礼预,都可以互相借鑒曼尊,取長補短。谷歌的code review經(jīng)驗實踐一直是業(yè)界比較認可的方式鸳碧,來看看谷歌怎么做的吧各淀。
代碼評審準則
一般來說懒鉴,如果 CL 達到可以提升系統(tǒng)整體代碼質(zhì)量的程度,就可以讓它們通過了碎浇,即使它們可能還不完美临谱。這是所有代碼評審準則的最高原則。
當然奴璃,也有例外的時候悉默。例如,如果 CL中包含了系統(tǒng)不需要的功能苟穆,那么即使代碼寫得很好抄课,評審人員也可以拒絕讓它們通過。
因為這個世界上沒有“完美”的代碼鞭缭,只有更好的代碼剖膳。評審人員不應該要求開發(fā)人員對 CL 中的每一個微小部分都進行細致入微的打磨,而應該在滿足需求和變更重要性之間做出權衡岭辣。評審人員不應該過度追求完美吱晒,而應追求持續(xù)改進。如果一個 CL 能夠從整體上提高系統(tǒng)的可維護性沦童、可讀性和可理解性仑濒,那它就不應該僅僅因為它不夠“完美”而被延遲幾天甚至幾周叹话。
以上是代碼評審的大指導方向。
代碼評審原則
我們再來看看具體的細分原則:
1.客觀的技術和數(shù)據(jù)比個人意見和偏好更重要
2.在代碼風格方面墩瞳,可以參考(谷歌風格指南)驼壶。任何沒有在這個風格指南中出現(xiàn)的東西(比如空格等)都屬于個人偏好。
3.如果沒有其他適用的原則喉酌,評審人員可以要求開發(fā)人員與當前代碼庫保持一致热凹,只要不破壞系統(tǒng)的整體代碼質(zhì)量。
代碼評審究竟要關注哪些方面泪电?
功能
這個 CL 是否有意義般妙?對戶來說有好處嗎?
設計
代碼評審中最重要的部分是 CL 的總體設計相速。
我們要考慮 CL 中不同代碼段之間的交互是有意義的嗎碟渺?
這個變更應該屬于代碼庫,還是屬于某個包突诬?
它與系統(tǒng)的其他部分可以良好地集成嗎苫拍?
現(xiàn)在是引入這個變更的好時機嗎?
評審人員要警惕過度設計旺隙,鼓勵開發(fā)人員只解決現(xiàn)在需要解決的問題绒极,而不是將來可能需要解決的問題。
未來的問題應該在它們出現(xiàn)之后再去解決蔬捷,因為到了那個時候我們可以看到它們的實際狀況和需求集峦。
過度設計是一種特殊的復雜性,開發(fā)人員把代碼寫得比實際需要的更通用抠刺,或者增加了系統(tǒng)當前不需要的功能。
復雜性
CL 比實際需要的更復雜嗎摘昌?
從每一層面檢查 CL速妖,細到每一行代碼,它們是不是太復雜了聪黎?“太復雜”通常意味著“閱讀代碼的人難以很快理解它們”罕容,也意味著“開發(fā)人員在調(diào)用或修改這些代碼時可能會引入 bug”。
測試
要求開發(fā)人員進行單元測試稿饰、集成測試或端到端測試锦秒。
一般來說,CL 中應該包含測試喉镰,除非這個 CL 只是為了處理緊急情況旅择。
請記住,測試代碼也是需要維護的侣姆。
命名
開發(fā)人員是否使用了良好的命名方式生真?
注釋
開發(fā)人員有沒有用自然語言寫出清晰的注釋沉噩?
他們所寫的注釋都是必需的嗎?
代碼風格
要確保 CL 遵循了適當?shù)闹改稀?/p>
請不要只是基于個人偏好來阻止 CL 的提交柱蟀。
開發(fā)人員不應該將風格變更與其他變更放在一起川蒙,這樣很難看出 CL 發(fā)生了哪些變化,導致合并和回滾變得更加復雜长已。
如果開發(fā)人員想要重新格式化整個文件畜眨,讓他們將重新格式化后的文件作為單獨的 CL,并將功能變更作為另一個 CL术瓮。
文檔
如果 CL 導致用戶構建康聂、測試、交互或發(fā)布代碼的方式發(fā)生了變化斤斧,請確保相關的文檔也得到了更新早抠,包括 README、g3doc頁和其他生成的參考文檔撬讽。
如果 CL 有移除或棄用代碼蕊连,請考慮一下是否也應該刪除相關的文檔。
查看每一行代碼
查看每一行代碼游昼,不要只是粗略地掃一下類甘苍、函數(shù)或代碼塊,并假定它們都能正常運行烘豌,至少應該要理解這些代碼都在做些什么载庭。
如果代碼很復雜或者你難以快速看懂它們,導致評審速度變慢廊佩,要讓開發(fā)人員知道囚聚,并在進行進一步評審之前讓他們做一些澄清。如果你看不懂這些代碼标锄,其他開發(fā)人員很可能也看不懂顽铸。因此,要求開發(fā)人員澄清代碼其實也是在幫助未來的開發(fā)人員更好地理解代碼料皇。
如果你理解代碼谓松,但又覺得沒有資格做代碼評審,可以確保有資格的 CL 評審人員在代碼評審時考慮到了安全性践剂、并發(fā)性鬼譬、可訪問性、國際化等問題逊脯。
上下文
代碼評審工具通常只顯示被修改的代碼优质,但有時候你需要查看整個文件,確保代碼變更是有意義的军洼。
例如盆赤,你可能只看到新添加了四行代碼贾富,但如果你看一下整個文件,會發(fā)現(xiàn)這四行代碼位于一個 50 多行的方法中牺六,這個時候需要將這個方法拆分為更小的方法颤枪。
好的一面
代碼評審通常只關注錯誤的東西,但其實也應該鼓勵和贊賞好的代碼實踐淑际。
如果你在 CL中看到一些不錯的東西畏纲,要讓開發(fā)人員知道,特別是當他們以一種很好的方式解決了問題春缕。
有時候盗胀,讓開發(fā)人員知道他們做對了事情比讓他們知道做錯了事情更有價值。
因此總結下來锄贼,在進行代碼評審時票灰,你要確保:
良好的代碼設計
功能對用戶來說是有用的
UI 變更應該是合理的
并行編程是安全的
代碼復雜性不要超過應有的程度
不需要實現(xiàn)可能會在未來出現(xiàn)的需求
有適當?shù)膯卧獪y試
精心設計的測試用例
使用了清晰的命名方式
清晰而有用的代碼注釋
恰如其分的代碼文檔化
代碼要遵循風格指南,而不是個人喜好
查看上下文宅荤,檢查每一行代碼
為表現(xiàn)不錯的開發(fā)人員點贊
評審流程
知道了代碼評審過程中要關注哪些點之后屑迂,是時候了解下代碼評審流程了。
第一步:從整體查看代碼變更
先看一下 CL 描述冯键,看看這個 CL 做了些什么惹盼。做出這個變更有意義嗎?如果這個變更是不必要的惫确,請立即做出回復手报,并解釋為什么不應該發(fā)生這個變更。在你拒絕這樣的變更時改化,可以向開發(fā)人員建議他們應該做些什么掩蛤。
第二步:檢查 CL 的主要部分
找到 CL 的主要文件。通常一個 CL 會有一個包含了主要邏輯變更的文件陈肛,也就是 CL 的主要部分盏档。先看看這些主要部分,有助于了解整個上下文燥爷,加快代碼評審速度。如果 CL 太大懦窘,以致于你無法確定哪些部分是主要的前翎,可以詢問開發(fā)人員,或者讓他們把 CL 拆分成多個 CL畅涂。
如果 CL 的主要部分存在嚴重的設計問題港华,要立即回復開發(fā)人員,即使你還沒有時間檢查 CL 的其余部分午衰。這個時候檢查 CL 的其余部分可能是在浪費時間立宜,因為如果主要部分存在嚴重的設計問題冒萄,那么其他部分就變得無關緊要了。
第三步:按照適當?shù)捻樞驒z查 CL 的其余部分
在確認整體 CL 沒有嚴重的設計問題之后橙数,試著按照某種邏輯順序來檢查其他文件尊流,確保不會錯過任何一個需要檢查的文件。通常灯帮,在你檢查完主要文件之后崖技,按照代碼評審工具顯示它們的順序來瀏覽每個文件就可以了。你也可以在檢查主要代碼之前先查看測試代碼钟哥,這樣可以對代碼變更有一個大致的概念迎献。
代碼評審回推
有時候,開發(fā)人員會回推代碼評審腻贰。他們可能不同意你的意見吁恍,或者他們抱怨你太嚴格了。
誰是對的播演?
如果開發(fā)人員不同意你的意見冀瓦,先花點時間想一下他們是不是對的。通常宾巍,他們比你更熟悉代碼咕幻,所以可能對代碼的某些方面更了解。他們的論點有道理嗎顶霞?從代碼質(zhì)量角度來看肄程,他們的回推是有道理的嗎?如果是选浑,就讓他們知道他們是對的蓝厌,這個問題就解決了。
然而古徒,開發(fā)人員并不總是正確的拓提。在這種情況下,評審人員要進一步解釋為什么他們的建議是正確的隧膘。
如果評審人員認為他們的建議可以改善代碼質(zhì)量代态,并認為評審所帶來的代碼質(zhì)量改進值得開發(fā)人員做出額外的工作,那么他們就應該堅持疹吃。改善代碼質(zhì)量往往是由一系列的小步驟組成的蹦疑。
有時候你需要花很多時間反復解釋,但要始終保持禮貌萨驶,并讓開發(fā)人員知道你知道他們在說什么歉摧。
激動的開發(fā)人員
有時候,評審人員會認為如果他們堅持要開發(fā)人員做出改動,會讓開發(fā)人員感到不安叁温。開發(fā)人員有時候確實會感到沮喪再悼,但這種感覺通常都很短暫,之后他們會非常感謝你幫助他們提高了代碼質(zhì)量膝但。如果你在評審過程中表現(xiàn)得很有禮貌冲九,開發(fā)人員一點都不會感到不安,這種擔心可能是多余的锰镀。通常娘侍,令開發(fā)人員感到不安的是你寫注解的方式,而不是你對代碼質(zhì)量的堅持泳炉。
稍后再解決
一種常見的回推原因是開發(fā)人員希望盡快完成任務憾筏。他們不想經(jīng)過一輪又一輪的代碼評審,他們說他們會在后續(xù)的 CL 中解決遺留問題花鹅,你現(xiàn)在讓 CL 通過就可以了氧腰。一些開發(fā)人員會做得很好,他們在提交 CL 后立即就開發(fā)后續(xù)的 CL刨肃。但經(jīng)驗表明古拴,開發(fā)人員開發(fā)原始 CL 的時間越長,他們進行后續(xù)修復的可能性就越小真友。除非開發(fā)人員在提交 CL 之后立即進行修復黄痪,否則在通過之后通常不會再去做這件事情。這并不是因為開發(fā)人員不負責任盔然,而是因為他們有很多工作要做桅打,而修復工作通常會被遺忘。所以愈案,最好讓開發(fā)人員馬上把 CL 修復掉挺尾。
如果 CL 引入了新的復雜性,在提交之前必須將其清理掉站绪,除非是緊急情況遭铺。如果 CL 暴露了一些目前還無法解決的問題,開發(fā)人員需要把 bug 記錄下來恢准,并將其分配給自己魂挂,這樣它就不會被遺漏。他們還可以在代碼中加入 TODO 注釋馁筐,指向已經(jīng)記錄好的 bug涂召。
抱怨評審太嚴格
如果你之前的代碼評審很放松,然后突然變得嚴格起來眯漩,可能會引起一些開發(fā)人員的抱怨。不過沒關系,加快代碼評審速度通常會讓這些抱怨逐漸消失赦抖。
有時候舱卡,這些抱怨可能需要幾個月的時間才能消除,但開發(fā)人員到最后通常會看到代碼評審的價值队萤,因為他們看到了嚴格的代碼評審有助于產(chǎn)出優(yōu)秀的代碼轮锥。有時候,抗議最大聲的人甚至會成為你最堅定的支持者要尔。
解決沖突
如果你遵循了上述方法舍杜,但仍然會在評審過程中遇到無法解決的沖突,請再次參閱代碼評審標準赵辕,了解那些有助于解決沖突的指導原則既绩。
代碼評審的速度
為什么代碼評審要快速進行?
在谷歌还惠,對開發(fā)團隊的整體交付速度(而不是針對個體開發(fā)人員寫代碼的速度)進行了優(yōu)化饲握。個體開發(fā)速度也很重要,但其重要性比不上整個團隊的開發(fā)速度蚕键。
如果代碼評審的速度很慢救欧,就會發(fā)生以下這些事情:
團隊的整體開發(fā)速度降低了。如果個體開發(fā)人員無法快速地對評審做出響應锣光,可能是因為他們有其他事情要做笆怠。但是,如果每個 CL 都要等待一次又一次的評審誊爹,那么其他成員的新特性和 bug 修復就會被延遲蹬刷,可能是幾天、幾周甚至是幾個月替废。
開發(fā)人員開始對代碼評審流程提出抗議箍铭。如果評審人員要隔幾天才回復一次,但每次都要求對CL 進行重大修改椎镣,開發(fā)人員可能會覺得很沮喪诈火。通常,他們會抱怨評審人員太過嚴苛状答。如果評審人員能夠快速提供反饋冷守,抱怨就會消失,即使他們要求做出的修改是一樣的惊科。代碼評審過程的大多數(shù)抱怨實際上可以通過加快評審速度來解決拍摇。
代碼質(zhì)量受影響。如果評審速度很慢馆截,開發(fā)人員的壓力也會隨之增加充活,因為他們不能提交不甚完美的 CL蜂莉。緩慢的評審流程還會阻礙代碼清理、重構和對現(xiàn)有 CL 做出進一步改進混卵。