代碼審查的價(jià)值——為何做、何時(shí)做、如何做?
對(duì)于很多公司來說,代碼審查是開發(fā)人員日常工作中的重要環(huán)節(jié)。通過代碼審查,可以及早發(fā)現(xiàn)項(xiàng)目中存在的問題、促進(jìn)同事之間的溝通與交流,并且可以在討論中迸發(fā)出智慧的火花。但要想成功實(shí)施代碼審查卻并不是一件輕松的事情,為什么要進(jìn)行代碼審查、何時(shí)做、如何做,這是擺在我們面前的3個(gè)重要問題。針對(duì)于這3個(gè)問題,開發(fā)者Lisa Tjapkes撰文談到了自己的經(jīng)驗(yàn)與教訓(xùn)。
在我最近的項(xiàng)目經(jīng)歷中,我們進(jìn)行了廣泛且正式的代碼審查。這個(gè)過程極大地改進(jìn)了項(xiàng)目的代碼質(zhì)量,降低了項(xiàng)目中新特性開發(fā)的等待時(shí)間,同時(shí)還促進(jìn)了知識(shí)在整個(gè)團(tuán)隊(duì)間的傳播與共享。我還發(fā)現(xiàn)代碼審查并不會(huì)延誤項(xiàng)目開發(fā)的時(shí)間,反而會(huì)提升開發(fā)人員的生產(chǎn)力。
代碼審查的好處
我們發(fā)現(xiàn)代碼審查對(duì)于項(xiàng)目的各個(gè)階段都會(huì)帶來很多好處:
- 在項(xiàng)目起始階段進(jìn)行代碼審查會(huì)幫助我們更好地使用已經(jīng)建立起來的代碼基,因?yàn)槿绻覀儧]有使用過某些現(xiàn)有代碼,那么可以從當(dāng)前的開發(fā)者中獲得反饋信息。
- 在項(xiàng)目進(jìn)行過程中,我們會(huì)時(shí)不時(shí)地向團(tuán)隊(duì)增加新的開發(fā)人員,代碼審查可以極大地降低這些新加入人員的熟悉時(shí)間。特別地,我們可以讓新加入的開發(fā)人員很有信心地開發(fā)新特性,因?yàn)槲覀兛梢栽诤喜⑶皩彶榇a并且對(duì)于他們所編寫的任何代碼提供有價(jià)值的反饋信息。
- 對(duì)于我們這個(gè)分布式團(tuán)隊(duì)來說,代碼審查更加具有實(shí)際意義。團(tuán)隊(duì)協(xié)同在構(gòu)建協(xié)作環(huán)境上會(huì)帶來很大的幫助作用,我們可以即時(shí)提出想法,然后討論,再進(jìn)行開發(fā)。雖然由于不在同一地點(diǎn)我們會(huì)失去一些東西,不過我們卻可以在代碼審查過程中通過深入的討論來獲得好處。
高效代碼審查的技巧
代碼審查的方式如果處理不當(dāng)可能會(huì)導(dǎo)致項(xiàng)目延期。使用正確的工具與技術(shù)可以防止在審查上浪費(fèi)大量的時(shí)間,提升代碼的品質(zhì)。
使用特性分支
這個(gè)實(shí)踐的好處就不用多說了,不過它對(duì)代碼審查提供了更加具體的好處。特性分支意味著你可以將需要審查的代碼隔離到只與某個(gè)具體的特性相關(guān)。在代碼已經(jīng)準(zhǔn)備好了審查時(shí),特性分支還考慮到了快速的上下文切換。在當(dāng)前的代碼進(jìn)行審查時(shí),你可以切換到新的特性上來,如果需要對(duì)審查特性的反饋進(jìn)行討論時(shí)還可以快速切換回來。
將審查隔離為小的修改
相對(duì)于大的修改來說,小修改的審查時(shí)間會(huì)更少。在審查大的修改時(shí),你不僅要看很多行代碼,還要查看大量的依賴代碼才能真正理解,結(jié)果就是花在審查代碼上的時(shí)間與修改的代碼量之間并不是呈線性關(guān)系。將待審查的代碼隔離為小的修改可以降低審查者的精神負(fù)擔(dān)并讓審查過程更加順暢。
使用專門為代碼審查而設(shè)計(jì)的工具
這看起來似乎很簡(jiǎn)單,但卻非常重要。一些重要的特性需要包含差異比較、能夠逐行注釋修改,并且在審查的代碼發(fā)生改變時(shí)通知大家。我所在的團(tuán)隊(duì)使用GitHub來管理項(xiàng)目代碼,并且使用GitHub的pull request特性來管理代碼審查。
檢查清單
可能沒必要使用非常復(fù)雜或是過于結(jié)構(gòu)化的東西,如果突然出現(xiàn)了某些問題,使用檢查清單或許是個(gè)不錯(cuò)的主意。
有建設(shè)性的輸入
類似于“多加點(diǎn)注釋”這樣的話顯得太沒意義了,幫助也不大。假如某個(gè)接口沒有注釋,但也許有專門的文檔用來說明呢。如果發(fā)現(xiàn)了某些不合理的地方,那就要明確指出來,判斷設(shè)計(jì)上是否能改進(jìn)或是邏輯上是否存在著錯(cuò)誤。
要把精力放在真正理解代碼的行為上,確保當(dāng)其他人需要維護(hù)它時(shí)也能夠快速理解代碼。
人人參與
即便是最有經(jīng)驗(yàn)的架構(gòu)師或是明星開發(fā)者也會(huì)犯錯(cuò)。因此,***每個(gè)人都能參與到代碼審查的過程中來。特別地,對(duì)于很多初級(jí)開發(fā)者或是新加入項(xiàng)目的開發(fā)者來說,這也是個(gè)很不錯(cuò)的學(xué)習(xí)機(jī)會(huì)。
要有審查流程
一開始,我們的項(xiàng)目并沒有正規(guī)的審查流程。我們只是開啟一個(gè)pull request,等待有人來審查,***會(huì)有人合并修改。這種工作方式效率非常差,有時(shí)好幾天都沒人審查一個(gè)pull request,有時(shí)一個(gè)人給出反饋前其他人卻合并了請(qǐng)求。此外,有些開發(fā)者審查的代碼量要比其他人多不少。總而言之,沒有流程導(dǎo)致我們的效率極低。
***我們認(rèn)識(shí)到了這一點(diǎn),創(chuàng)建了一個(gè)正式的結(jié)構(gòu)來指導(dǎo)該如何進(jìn)行代碼審查,這加速了審查的效率。一個(gè)審查過程至少應(yīng)該涵蓋如下幾點(diǎn):
- 如何將審查任務(wù)分派給不同的人
- 期待審查者給出反饋的最遲時(shí)間
- 如何標(biāo)識(shí)某個(gè)審查已經(jīng)完成
- 誰(shuí)負(fù)責(zé)合并已經(jīng)完成審查的代碼
我在項(xiàng)目中是否應(yīng)該進(jìn)行代碼審查?
我認(rèn)為代碼審查對(duì)于很多項(xiàng)目來說都是一件好事,不過它也并非通用的解決方案。代碼審查適合于如下這些項(xiàng)目:
- 至少有5名開發(fā)人員
- 在向團(tuán)隊(duì)增加新的開發(fā)人員時(shí)
- 團(tuán)隊(duì)是分布式的
- 項(xiàng)目有各種不同的組件構(gòu)成,這些組件是由不同團(tuán)隊(duì)開發(fā)的
- 當(dāng)還處在為代碼基設(shè)定約定以及***實(shí)踐的階段
- 團(tuán)隊(duì)中有些成員對(duì)于當(dāng)前所使用的技術(shù)棧還不太熟悉時(shí)
相反,代碼審查在如下的情形中并不會(huì)為項(xiàng)目帶來更多的附加值:
- 處理的是維護(hù)代碼而不是添加新的特性
- 團(tuán)隊(duì)很小且親密無(wú)間