同行代碼審查(Peer Code Review)實戰經驗
為什麼要做Code review?
每個專業軟體開發者都有一個重要的目標:持續的提高他們的工作質量。即使你團隊中都是一些優秀的程序員,但是你依然不能將你自己與一個有能力的自由職業者區分開來,除非你從團隊的角度來工作。Code review是團隊工作的一個重要的方面。尤其是:
代碼複查者(reviewer)能從他們的角度來發現問題並且提出更好的解決方案。
確保至少你團隊的另一個其他成員熟悉你的代碼,通過給新員工看有經驗的開發者的代碼能夠某種程度上提高他們的水平。
公開reviewer和被複查者的想法和經驗能夠促進團隊間的知識的分享。
能夠鼓勵開發者將他們的工作進行的更徹底,因為他們知道他們的代碼將被其他的人閱讀。
在review的過程中的注意點
但是,由於Code review的時間有限,上面所說的目標未必能全部達到。就算只是想要打一個補丁,都要確保意圖是正確的。如果只是將變數名改成駱駝拼寫法(camelCase),那不算是code review。在開發過程中進行結對編程是有益處的,它能夠使兩個人得到公平的鍛煉。你能夠在code review上花許多時間,並且仍然能夠比在結對編程中使用更少的時間。
我的感受是,在項目開發的過程中,25%的時間應該花費在code review上。也就是說,如果開發者用兩天的時間來開發一個東西,那麼複查者應該使用至少四個小時來審查。
當然,只要你的review結果準確的話,具體花了多少時間就顯得不是那麼的重要。重要的是,你能夠理解你看的那些代碼。這裡的理解並不是指你看懂了這些代碼書寫的語法,而是你要知道這段代碼在整個龐大的應用程序、組件或者庫中起著什麼樣的作用。如果你不理解每一行代碼的作用,那麼換句話說,你的code review就是沒有價值的。這就是為什麼好的code review不能很快完成的原因。需要時間來探討各種各樣的代碼路徑,讓它們觸發一個特定的函數,來確保第三方的API得到了正確的使用(包括一些邊緣測試)。
為了查閱你所審查的代碼的缺陷或者是其他問題,你應該確保:
- 所有必要的測試都已經被包含進去。
- 合理的設計文檔已經被編寫。
再熟練的開發者也不是每次都會記得在他們對代碼改動的時候把測試程序和文檔更新上去。來自reviewer的一個提醒能夠使得測試用例和開發文檔不會一直忘了更新。
避免code review負擔太大
如果你的團隊沒有強制性的code review,當你的code review記錄停留在無法管理的節點上時會很危險。如果你已經兩周沒有進行code review了,你可以花幾天的時間來跟上項目的進度。這意味著你自己的開發工作會被阻斷,當你想要處理之前遺留下來的code review的時候。這也會使得你很難再確保code review的質量,因為合理的code review需要長期認真的努力,最終會很難持續幾天都保持這樣的狀態。
由於這個原因,開發者應當每天都完成他們的review任務。一種好辦法就是將code review作為你每天的第一件事。在你開始自己的開發工作之前完成所有的code review工作,能夠使你從頭到尾都集中注意力。有些人可能更喜歡在午休前或午休後或者在傍晚下班前做review。無論你在哪個時間做,都要將code review看作你的工作之一併且不能分心,你要避免:
- 沒有足夠的時間來處理你的review任務。
- 由於你的code review工作沒有做完導致版本的推遲發布。
- 提交不再相關的review,由於代碼在你review期間已經改動太大。
- 因為你要在最後一分鐘完成他們,以至於review質量太差。
書寫易於review的代碼
有時候review沒有按時完成並不都是因為reviewer。如果我的同事使用一周時間在一個大工程中添加了一些亂七八糟的代碼,且他們提交的補丁實在是太難以閱讀。在一段代碼中有太多的東西要瀏覽。這樣會讓人難以理解它的作用,自然會拖慢review的進度。
為什麼將你的工作劃分成一些易於管理的片段很重要有很多原因。我們使用scrum方法論(一種軟體開發過程方法),因此對我們來說一個合理的單元就是一個story。通過努力將我們的工作使用story組織起來,並且只是將review提交到我們正在工作的story上,這樣,我們寫的代碼就會更加易於review。你們也可以使用其他的軟體開發方法,但是目的是一樣的。
書寫易於review的代碼還有其他先決條件。如果要做一些複雜的架構決策,應該讓reviewer事先知道並參與討論。這會讓他們之後review你們的代碼更加容易,因為他們知道你們正在試圖實現什麼功能並且知道你們打算如何來實現。這也避免了開發者需要在reviewer提了一個不同的或者更好的解決方案後大片的重寫代碼。
項目需要應當在設計文檔中詳細的描述。這對於一個項目新成員想要快速上手並且理解現有的代碼來說非常重要。這從長遠角度對於一個reviewer來說也非常有好處。單元測試也有助於reviewer知道一些組件是怎麼使用的。
如果你在你的補丁中包含的第三方的代碼,記得單獨的提交它。當jQuery的9000行代碼被插入到了項目代碼的中間,毫無疑問會造成難以閱讀。
創建易讀的review代碼的另一個非常重要的措施是添加相應的注釋代碼。這就要求你事先自己做一下review並且在一些你認為會幫助reviewer進行review的地方加上相應的注釋。我發現加上注釋相對於你來說往往只需要很短的時間(通常是幾分鐘),但是對於review來說會節約很多的時間。當然,代碼注釋還有其他相似的好處,應該在合理的地方使用,但往往對code review來說更重要。事實上,有研究表明,開發者在重讀並注釋他們代碼的過程中,通常會發現很多問題。
代碼大範圍重構的情況
有時候,有必要重構一段代碼使其能夠作用於多個其他組件。若是一個大型的應用要這樣做,會花費幾天甚至是更多的時間,結果是生成一個諾大的補丁包。在這種情況下,進行一個標準的code review可能是不切實際的。
最好的方法是增量重構你的代碼。找出合理範圍內的一部分改變,以此為基礎來重構。一旦修改和review完成,進入第二個增量。以此類推,直到整個重構完成。這種方法可能不是在所有的情況下都可行,但是儘管如此,也能避免在重構時出現大量的單片補丁。開發者使用這種方式重構可能會花去更多的時間,但這也使得代碼質量更高並且之後的review會更簡單。
如果實在是沒有條件去通過增量方式重構代碼(有人可能會說之前的代碼書寫並組織的是多麼的好),一種解決方案是在重構時進行結對編程來代替code review。
解決團隊成員之間的糾紛
你的團隊中都是一些有能力的專家,在一些案例中,完全有可能因為對一個具體編碼問題的意見的不同而產生爭論。作為一個開發者,應該保持一個開發的頭腦並且時刻準備著妥協,當你的reviewer更想要另一種解決方法時。不要對你的代碼持有專有的態度,也不要自己持有審查的意見。因為有人會覺得你應該將一些重複的代碼寫入一個能夠復用的函數中去,這並不意味著這是你的問題。
作為一個reviewer,要靈活。在提出修改建議之前,考慮你的建議是否真的更好或者只是無關緊要。如果你把力氣和注意力花在那些原來的代碼會明確需要改進的地方會更加成功。你應該說"它或許值得考慮..."或者"一些人建議..."而不是」我的寵物都能寫一個比這個更加有效的排序方法"。
如果你真的決定不了,那就詢問另一個你及你所審查的人都尊敬的開發者來聽一下你意見並給出建議。
via: http://blog.salsitasoft.com/practical-lessons-in-peer-code-review/
本文轉載來自 Linux 中國: https://github.com/Linux-CN/archive