我一直認為Code Review(代碼審查)是軟件開(kāi)發(fā)中的最佳實(shí)踐之一,可以有效提高整體代碼質(zhì)量,及時(shí)發(fā)現代碼中可能存在的問(wèn)題。包括像Google、微軟這些公司,Code Review都是基本要求,代碼合并之前必須要有人審查通過(guò)才行。
然而對于我觀(guān)察到的大部分軟件開(kāi)發(fā)團隊來(lái)說(shuō),認真做Code Review的很少,有的流于形式,有的可能根本就沒(méi)有Code Review的環(huán)節,代碼質(zhì)量只依賴(lài)于事后的測試。也有些團隊想做好代碼審查,但不知道怎么做比較好。
網(wǎng)上關(guān)于如何做Code Review的文章已經(jīng)有很多了,這里我結合自己的一些經(jīng)驗,也總結整理了一下Code Review的最佳實(shí)踐,希望能對大家做好Code Review有所幫助。
Code Review有什么好處?
很多團隊或個(gè)人不做Code Review,根源還是不覺(jué)得這是一件有意義的事情,不覺(jué)得有什么好處。這個(gè)問(wèn)題要從幾個(gè)角度來(lái)看。
•首先是團隊知識共享的角度
一個(gè)開(kāi)發(fā)團隊中,水平有高有低,每個(gè)人側重的領(lǐng)域也有不同。怎么讓高水平的幫助新人成長(cháng)?怎么讓大家都對自己側重領(lǐng)域之外的知識保持了解?怎么能有人離職后其他人能快速接手?這些都是團隊管理者關(guān)心的問(wèn)題。
而代碼審查,就是一個(gè)很好的知識共享的方式。通過(guò)代碼審查,高手可以直接指出新手代碼中的問(wèn)題,新手可以馬上從高手的反饋中學(xué)習到好的實(shí)踐,得到更快的成長(cháng);通過(guò)代碼審查,前端也可以去學(xué)習后端的代碼,做功能模塊A的可以去了解功能模塊B的。
可能有些高手覺(jué)得給新手代碼審查浪費時(shí)間,自己也沒(méi)收獲。其實(shí)不然,新人成長(cháng)了,就可以更多的幫高手分擔繁重的任務(wù);代碼審查中花時(shí)間,就少一些幫新人填坑擦屁股的時(shí)間;良好的溝通能力、發(fā)現問(wèn)題的能力、幫助其他人成長(cháng),都是技術(shù)轉管理或技術(shù)上更上一層樓必不可少的能力,而通過(guò)代碼審查可以有效的去練習這些方面的能力。
•然后是代碼質(zhì)量的角度
現實(shí)中的項目總是人手缺進(jìn)度緊,所以被壓縮的往往就是自動(dòng)化測試和代碼審查,結果影響代碼質(zhì)量,欠下技術(shù)債務(wù),最后還是要加倍償還。
也有人寄希望于開(kāi)發(fā)后的人工測試,然而對于代碼質(zhì)量來(lái)說(shuō),很多問(wèn)題通過(guò)測試是測試不出來(lái)的,只能通過(guò)代碼審查。比如說(shuō)代碼的可讀性可維護性,比如代碼的結構,比如一些特定條件才觸發(fā)的死循環(huán)、邏輯算法錯誤,還有一些安全上的漏洞也更容易通過(guò)代碼審查發(fā)現和預防。
也有人覺(jué)得自己水平高就不需要代碼審查了。對于高手來(lái)說(shuō),讓別人審查自己的代碼,可以讓其他人學(xué)習到好的實(shí)踐;在讓其他人審查的同時(shí),在給別人說(shuō)明自己代碼的時(shí)候,也等于自己對自己的代碼進(jìn)行了一次審查。這其實(shí)就跟我們上學(xué)時(shí)做數學(xué)題一樣,真正能拿高分的往往是那些做完后還會(huì )認真檢查的。
•還有團隊規范的角度
如果這些違反規范的代碼被糾正的晚了,后面再要修改就成本很高了,而且團隊的規范也會(huì )慢慢的形同虛設。
每個(gè)團隊都有自己的代碼規范,有自己的基于架構設計的開(kāi)發(fā)規范,然而時(shí)間一長(cháng),就會(huì )發(fā)現代碼中出現很多不遵守代碼規范的情況,有很多繞過(guò)架構設計的代碼。比如難以理解和不規范的命名,比如三層架構里面UI層繞過(guò)業(yè)務(wù)邏輯層直接調用數據訪(fǎng)問(wèn)層代碼。
通過(guò)代碼審查,就可以及時(shí)的去發(fā)現和糾正這些問(wèn)題,保證團隊規范的執行。
關(guān)于代碼審查的好處,還有很多,也不一一列舉。還是希望能認識到Code Review和寫(xiě)自動(dòng)化測試一樣,都是屬于磨刀不誤砍柴工的工作,在上面投入一點(diǎn)點(diǎn)時(shí)間,未來(lái)會(huì )收獲代碼質(zhì)量,會(huì )節約整體的開(kāi)發(fā)時(shí)間。
該怎么做?
現在很多人都已經(jīng)有意識到Code Review的重要性了,只是苦于不知道如何去實(shí)踐,不知道怎么樣算是好的Code Review實(shí)踐。
在很早以前,我就嘗試過(guò)將代碼審查作為代碼流程的一部分,但只是一個(gè)可選項,沒(méi)有Code Review也可以把代碼合并到master。這樣的結果就是想起來(lái)才會(huì )去做Code Review,去檢查的時(shí)候已經(jīng)有了太多的代碼變更,審查起來(lái)非常困難,另外就算審查出問(wèn)題,也很難得以修改。
我們現在對代碼的審查則是作為開(kāi)發(fā)流程的一個(gè)必選項,每次開(kāi)發(fā)新功能或者修復Bug,開(kāi)一個(gè)新的分支,分支要合并到master有兩個(gè)必要條件:
•所有的自動(dòng)化測試通過(guò)•有至少一個(gè)人Code Review通過(guò),如果是新手的PR,還必須有資深程序員Code Review通過(guò)
圖片來(lái)源:How to Do Code Reviews Like a Human
這樣把Code Review作為開(kāi)發(fā)流程的一個(gè)必選項后,就很好的保證了代碼在合并之前有過(guò)Code Review。而且這樣合并前要求代碼審查的流程,好處也很明顯:
•由于每一次合并前都要做代碼審查,這樣一般一次審查的代碼量也不會(huì )太大,對于審查者來(lái)說(shuō)壓力也不會(huì )太大•如果在Code Review時(shí)發(fā)現問(wèn)題,被審查者希望代碼能盡快合并,也會(huì )積極的對審查出來(lái)的問(wèn)題進(jìn)行修改,不至于對審查結果太過(guò)抵觸
如果你覺(jué)得Code Review難以推行,不妨先嘗試著(zhù)把Code Review變成你開(kāi)發(fā)流程的一個(gè)必選項。
把Code Review 作為開(kāi)發(fā)流程的必選項后,不代表Code Review這件事就可以執行的很好,因為Code Review 的執行,很大部分程度上依賴(lài)于審查者的認真審查,以及被審查者的積極配合,兩者缺一不可!
如果僅僅只是當作一個(gè)流程制度,那么就可能會(huì )流于形式。最終結果就是看起來(lái)有Code Review,但沒(méi)有人認真審查,隨便看下就通過(guò)了,或者發(fā)現問(wèn)題也不愿意修改。
真要把Code Review這件事做好,必須讓Code Review變成團隊的一種文化,開(kāi)發(fā)人員從心底接受這件事,并認真執行這件事。
要形成這樣的文化,不那么容易,也沒(méi)有想象的那么難,比如這些方面可以參考:
•首先,得讓開(kāi)發(fā)人員認識到Code Review這件事為自己、為團隊帶來(lái)的好處•然后,得要有幾個(gè)人做好表率作用,榜樣的力量很重要•還有,對于管理者來(lái)說(shuō),你激勵什么,往往就會(huì )得到什么•最后,像寫(xiě)自動(dòng)化測試一樣,把Code Review要作為開(kāi)發(fā)任務(wù)的一部分,給審查者和被審查者都留出專(zhuān)門(mén)的時(shí)間去做這件事,不能光想著(zhù)馬兒跑得快又舍不得給馬兒吃草
如何形成這樣的文化,有心的話(huà),還有很多方法可以嘗試。只有真正讓大家都認同和踐行,才可能去做好Code Review這件事。
一些Code Review的經(jīng)驗技巧
在做好Code Review這件事上,還有一些經(jīng)驗技巧可以參考。
選什么工具輔助做CODE REVIEW?
現在很多源代碼管理工具都自帶Code Review工具,典型的像Github、Gitlab、微軟的Azure DevOps,尤其是像Gitlab,還可以自己在本地搭建環(huán)境,根據自己的需要靈活配置。
配合什么樣的開(kāi)發(fā)流程比較好?
像Github Flow[1]這樣基于分支開(kāi)發(fā)的流程是特別適合搭配Code Review的。其實(shí)不管什么樣的開(kāi)發(fā)流程,關(guān)鍵點(diǎn)在于代碼合并到master(主干)之前,要先做Code Review。
雖然原則上,必須要Code Review才能合并,但有時(shí)候確實(shí)會(huì )存在一些緊急情況,比如說(shuō)線(xiàn)上故障補丁,而又沒(méi)有其他人在線(xiàn),那么這種情況下,最好是在任務(wù)管理系統中,創(chuàng )建一個(gè)Ticket,用來(lái)后續跟蹤,確保后續補上Code Review,并對Code Review結果有后續的代碼更新。
先設計再編碼
有些新人發(fā)現自己的代碼提交PR(Pull Request)后,會(huì )收到一堆的Code Review意見(jiàn),必須要做大量的改動(dòng)。這多半是因為在開(kāi)始做之前,沒(méi)有做好設計,做出來(lái)后才發(fā)現問(wèn)題很多。
建議在做一個(gè)新功能之前,寫(xiě)一個(gè)簡(jiǎn)單的設計文檔,表達清楚自己的設計思路,找資深的先幫你做一下設計的審查,發(fā)現設計上的問(wèn)題。設計上沒(méi)問(wèn)題了,再著(zhù)手開(kāi)發(fā),那么到Review的時(shí)候,相對問(wèn)題就會(huì )少很多。
代碼在提交CODE REVIEW之前,作者要自己先REVIEW和測試一遍
我在做代碼審查的時(shí)候,有時(shí)候會(huì )發(fā)現一些非常明顯的問(wèn)題,有些甚至自己都沒(méi)有測試過(guò),就等著(zhù)別人Code Review和測試幫助發(fā)現問(wèn)題。這種依賴(lài)心理無(wú)論是對自己還是對團隊都是很不負責任的。
一個(gè)好的開(kāi)發(fā)人員,代碼在提交Code Review之前,肯定是要自己先Review一遍,把該寫(xiě)的自動(dòng)化測試代碼寫(xiě)上,自己把基本的測試用例跑一遍的。
我對于團隊提交的PR,有個(gè)要求就是要在PR的描述中增加截圖或者錄屏,就是為了通過(guò)截圖或者錄屏,確保提交PR的人自己是先測試過(guò)的。這也是一個(gè)有效的輔助手段。
PR要小
在做Code Review的時(shí)候,如果有大量的文件修改,那么Review起來(lái)是很困難的,但如果PR比較小,相對就比較容易Review,也容易發(fā)現代碼中可能存在的問(wèn)題。
所以在提交PR時(shí),PR要小,如果是比較大的改動(dòng),那么最好分批提交,以減輕審查者的壓力。
對評論進(jìn)行分級
在做Code Review時(shí),需要針對審查出有問(wèn)題的代碼行添加評論,如果只是評論,有時(shí)候對于被審查者比較難甄別評論所代表的含義,是不是必須要修改。
類(lèi)似這樣的分級可以幫助被審查者直觀(guān)了解Review結果,提高Review效率。
評論要友好,避免負面詞匯;有說(shuō)不清楚的問(wèn)題當面溝通
雖然評論是主要的Code Review溝通方式,但也不要過(guò)于依賴(lài),有時(shí)候面對面的溝通效率更高,也容易消除誤解。
另外文明用語(yǔ),不要用一些負面的詞匯。
總結
Code Review是一種非常好的開(kāi)發(fā)實(shí)踐,如果你還沒(méi)開(kāi)始,不妨逐步實(shí)踐起來(lái);如果已經(jīng)做了效果不好,不妨對照一下,看有沒(méi)有把Code Review作為開(kāi)發(fā)流程的必選項而不是可選項?有沒(méi)有把Code Review變成一種開(kāi)發(fā)文化而不僅僅是一種制度?
原文轉自:http://t.cn/AilIWVbO