|
Jim Bird是一位經(jīng)驗(yàn)豐富的軟件開發(fā)經(jīng)理、項(xiàng)目經(jīng)理與CTO,專注于軟件開發(fā)與維護(hù)、軟件質(zhì)量與安全等領(lǐng)域中疑難問題的解決。在過去的15年間,Jim曾管理過團(tuán)隊(duì)建設(shè)并主導(dǎo)過高性能的財(cái)務(wù)系統(tǒng)的建設(shè)。他的主要興趣在于如何提升小團(tuán)隊(duì)的效率以構(gòu)建真正的軟件:高質(zhì)量、安全、可靠、高性能及適應(yīng)性強(qiáng)。近日,Jim撰寫了一篇博文,談到了代碼審查的價值,如何進(jìn)行代碼審查,代碼審查的過程以及在代碼審查中需要注意的問題,希望能為大家平日的代碼審查帶來一些啟示。
開始代碼審查
從一開始,開發(fā)者就會互相幫助,如果測試中遇到了問題或是有新人加入到了團(tuán)隊(duì),領(lǐng)導(dǎo)或是資深開發(fā)者就會審查他們的代碼。除此之外,我們還聘請了外部專家進(jìn)行安全代碼審查。
系統(tǒng)發(fā)布后,我們決定更加主動一些,開始了基于風(fēng)險(xiǎn)的審查:項(xiàng)目中有人會編寫一些風(fēng)險(xiǎn)較高的代碼(比如說框架與安全代碼、APIs、核心業(yè)務(wù)邏輯或是之前曾經(jīng)出現(xiàn)過問題的地方),我們會審查他們的代碼。在這個過程中,代碼審查體現(xiàn)出了它的價值,我們收獲頗豐。即便如此,我們還是更進(jìn)一步,讓代碼審查成為一個標(biāo)準(zhǔn)的實(shí)踐。
這并不是一夜之間就形成的。讓團(tuán)隊(duì)相信代碼審查的價值并不是什么難事,他們已經(jīng)通過基于風(fēng)險(xiǎn)的審查獲得了收益。不過要想改變?nèi)藗兊墓ぷ鞣绞骄筒皇悄敲春唵蔚氖虑榱耍€要確保他們有足夠的時間進(jìn)行代碼審查,理解并對反饋?zhàn)鞒鲰憫?yīng)。此外,設(shè)計(jì)一個高效的代碼審查流程也是需要花時間的。
一開始,我們讓開發(fā)者選擇好搭檔并安排審查,但結(jié)果卻有些混亂。有時,開發(fā)者會尋找那些好說話或是比較忙的人,這樣審查就比較容易通過了;此外,兩個開發(fā)者還有可能事先商量好,因此審查過程就會很快結(jié)束。由于人們并不知道要花費(fèi)多少時間才能完成代碼審查,因此審查經(jīng)常會拖得很久,常常在代碼已經(jīng)完成測試甚至是發(fā)布后才完成。
由于大多數(shù)人并沒有太多的代碼審查經(jīng)驗(yàn),因此他們并不確定在審查時應(yīng)該看什么,如何給出有意義的反饋等信息。開發(fā)者常常會被負(fù)面的批評搞得很沮喪,有時甚至?xí)臒┮鈦y。
最后,我們決定由領(lǐng)導(dǎo)來完成大部分審查工作。雖然這會增加領(lǐng)導(dǎo)的工作量,也意味著他們沒有太多時間編寫代碼了,不過這么做卻是很有效果的。通常情況下,主開發(fā)者會對需求有著更好的理解,對代碼的行為有著清晰的認(rèn)識,這也意味著他們更有可能發(fā)現(xiàn)代碼中的錯誤。由于是同一個人完成了大部分的代碼審查,因此被審查的開發(fā)者會收到一致的反饋信息。
我們?nèi)绾芜M(jìn)行代碼審查
在過去的幾年間,我們進(jìn)行代碼審查的方式幾乎沒有發(fā)生過什么大的變化。
無論是誰編寫的,無論代碼的功能是什么,重要的代碼變更是一定要審查的。我們并沒有一個正式的審查會議,也沒發(fā)現(xiàn)使用諸如Code Collaborator、Crucible等工具有什么必要性,不過現(xiàn)在看起來使用這些工具來管理和追蹤審查有助于團(tuán)隊(duì)更好的起步。
有時,審查是面對面完成的,不過大多數(shù)時候都是離線進(jìn)行的。審查者與開發(fā)者會交換信息,也許通過郵件發(fā)送文件,因?yàn)槲覀冇X得這種方式更加便捷,也更加方便每一個人安排自己的時間。
隨著時間的流逝,審查中的變化之處是審查者該看什么,以及看到的結(jié)果。
審查正確性
很多時候,程序員們會花費(fèi)很多時間爭論在代碼審查過程中應(yīng)該看什么,但實(shí)際上他們卻沒有花太多時間完成真正的代碼審查。
我們開始代碼審查的目的是改進(jìn)代碼質(zhì)量,尋找測試中沒有發(fā)現(xiàn)的問題。這么做并不是教授經(jīng)驗(yàn)不足的開發(fā)者如何編寫更好的代碼,或是如何在團(tuán)隊(duì)內(nèi)分享知識。這些都應(yīng)該是代碼審查所帶來的間接好處,不過審查的最終目的應(yīng)該是確保代碼能夠正常工作。
相對于使用長長的檢查列表,審查者在看代碼時首先會問幾個問題:
- 代碼的行為是否與預(yù)期一致,其邏輯是否是正確無誤的?
- 被審查的代碼是否與其他代碼擁有類似的結(jié)構(gòu)和功能?
審查可理解性
隨著時間的流逝,在代碼審查中尋找和得到的東西會發(fā)生變化。這是因?yàn)榇a本身會發(fā)生變化,完成這項(xiàng)工作的人——開發(fā)者與審查者也可能發(fā)生變化。
開發(fā)者需要在其IDE中裝上代碼檢查工具,同時我們也要使用一些優(yōu)秀的靜態(tài)分析工具來自動檢查常見的編碼Bug和不好的編碼實(shí)踐。這意味著審查者的時間可以花在更加重要的設(shè)計(jì)錯誤上,比如說并發(fā)Bug、競態(tài)條件和潛在的死鎖等,因?yàn)檫@些問題是工具所無法檢測到的。
理解,而不是批評
審查的目的是理解代碼,確保代碼能夠正常工作,而不是批評任何人。
在代碼審查過程中,請不要摻入諸如“我認(rèn)為好的代碼是什么,你認(rèn)為好的代碼是什么”這樣的論戰(zhàn)之中。代碼審查應(yīng)該重點(diǎn)關(guān)注“我需要完全理解這部分代碼才能確保它能夠正常工作,如果由我來修復(fù)代碼中的問題,我是不會這么寫的,因此希望你也不要這么來寫”。
隨著時間的流逝,有些東西會變好,有些則不然
隨著時間的流逝,在查看代碼時你會發(fā)現(xiàn)代碼在不斷變化。Michael Feathers發(fā)現(xiàn)大部分代碼在寫完后很少或是從來都不會變化;大部分變更都是發(fā)生在代碼基中的很小一部分代碼上的。
由于審查者會看到相同的代碼在不斷發(fā)生著變化,因此這也會改變他們的審查方式。
避免收益遞減
類似于軟件開發(fā)中的其他實(shí)踐一樣,你最終會發(fā)現(xiàn)代碼審查有著收益遞減的效應(yīng),特別是一直在做相同的事情的時候,以相同的方式查看相同的問題。最終會有這樣一個階段,那就是代碼審查的價值幾乎降到了0。不過這種情況并沒有發(fā)生在我們身上,我們依然從代碼審查過程中獲得了很多收益。
即便改進(jìn)了工具,增強(qiáng)了測試能力,我們依然進(jìn)行代碼審查,因?yàn)锽ug檢查工具、審查與測試會發(fā)現(xiàn)不同類型的問題。我們還發(fā)現(xiàn)代碼審查會讓測試更加高效,這是因?yàn)槿绻霸?jīng)發(fā)現(xiàn)過問題,那么開發(fā)者與測試者之間就不會出現(xiàn)過多的往復(fù)情況。
it知識庫:我們?nèi)绾芜M(jìn)行代碼審查,轉(zhuǎn)載需保留來源!
鄭重聲明:本文版權(quán)歸原作者所有,轉(zhuǎn)載文章僅為傳播更多信息之目的,如作者信息標(biāo)記有誤,請第一時間聯(lián)系我們修改或刪除,多謝。