資深的程序員都知道 Code Review 可以對代碼質量,代碼規范,團隊代碼能力提升帶來很大的提升,還有著名的技術專家“左耳朵耗子”也說過:
我認為沒有 Code Review 的公司都沒有必要呆(因為不做 Code Review 的公司一定是不尊重技術的)
- 出自《程序員的練級攻略 - 修養篇》
國外很多技術公司都非常重視 Code Review 也都做的特別好,例如 Google,亞馬遜,但是國內很多公司在踐行 Code Review 的時候卻是步履蹣跚,步步艱難,選用的方法不對,最終導致事倍功半的結果,總結一下我見過的幾種情況:
- 因為 Code Review 導致團隊成員之間相互指責,團隊凝聚力產生間隙
- Code Review 形式化,沒有提升代碼質量,減少 bug,反而降低開發效率
- Code Review 確實產生了效果,但是因為流程太重,導致團隊效率降低
我們也在踐行 Code Review,探索的路上也遇到一些障礙和經驗,總結分享一下,如果你也遇到這些問題,或許可以花一點時間讀一讀這篇文章,說不定會有幫助。
Code Review 能帶來哪些好處,本文就不說了,大家都很熟悉了,本文主要簡單說一下 Code Review 有哪幾個基本的共識和原則:
- Code Review 高效的原則是用機器去做大部分的事情
- Code Review 的時機(天時地利人和)
- 推行 Code Review 的關鍵原則
Code Review 高效的原則是用機器去做大部分的事情
不同的語言的格式和風格都是比較固定的,例如我最熟悉的 Java 語言常見的風格有以下幾種規范:
- Order Java SE 的標准規范:https://www.oracle.com/technetwork/java/codeconvtoc-136057.html
- Google Java 開發規范: https://google.github.io/styleguide/javaguide.html
- 阿里巴巴 Java 開發手冊:https://github.com/alibaba/p3c (國內常用)
還有我最近常用的 Ruby 語言,官方所推崇的幾種風格規范:
- Ruby Style Guide:https://github.com/rubocop-hq/ruby-style-guide
- Airbnb Ruby Style:https://github.com/airbnb/ruby
但凡是標准規范都是比較機械化的條條框框,應該交給機器去檢查(常用的工具由:P3C,Rubocop,SonarQube 等),機器靜態掃描效率不僅比人高出一個數量級,而且非常嚴謹,不容易出錯,甚至可以武斷的說:所有的自動化工具的本質,都是為了要減少對人的依賴性,因為人本身是具備很多種不確定性,所以並不適合做一些需要確定性並且反復重復的事情
Code Review 的時機(天時地利人和)
在以往的工作經驗中,Code Review 越是靠左移,修改代碼的成本越低,開發人員的修改意願也就越高,那什么叫左移?
我們看一下軟件開發的流水線和個人認為最合理的 code review 時機:
軟件工程的開發流水線(圖)
從流水線上來說,有些人會在臨近上線,在靠右的地方合並 master 的時候才進行 code review,這個時候修改成本就很高,因為代碼已經測試過,如果因為 code review 有問題需要重新修改代碼,那么功能本身又要回歸測試,占用的測試雙倍的時間,對於人力資源是雙倍的浪費,因為已經臨近上線,卻因為 code review 被打回,開發人員願意重構代碼的意願也會很低,如果明明發現問題,又因為上線壓力,不打回不符合規范的代碼,那么久而久之大家失去對 code review 的敬畏心理,code review 也會慢慢變成形式化,應用發布流程而已,既不能提高代碼質量,降低系統 Bug,也不能提升開發人員的水平,反而降低的開發團隊的效率,所以選擇在上線前進行 code review 不是一個好主意,所以從性價比上來說 code review 最好的時機應該是在 功能分支自測完成后,需要合並到 develop 分支申請提測前 通知項目組成員對增量的代碼進行 code review。
所以,代碼審查要高效的話,核心就是要追求快速反饋,越早發現代碼問題修改的成本就越低,具體參考下圖:
這里需要注意的是,代碼在經過機器掃描后(這里有一個技巧就是可以在 GitLab CI 加入自動的代碼風格檢查,代碼靜態掃描是一個高頻操作,一天可能會有幾十,甚至上百次的 Commit,如果接入 GitLab CI 實現自動化靜態掃描,大家不需要在自己本地執行靜態掃描,那么效率也會大大的提升),項目組成員只需要把注意力放在 代碼邏輯結構,功能設計的可維護,可擴展性 等機器不容易發現問題的地方上,然后就完成代碼審查。因為代碼還未提測,所以就算 Merge Request 不合格被打回后,因為還未提測,也不會占用測試人員的資源,開發人員的修改意願也會更高,總體來說是可以達到高效和質量的要求
Code Review 要計入開發的工作量
很多團隊不做 code review 都有一個共同的原因是覺得浪費時間,結果導致糟糕的代碼合並入庫,頻繁出現線上問題,然后開發人員疲於奔命的去修復線上事故 BUG,雖然短期來看功能是快速上線了,但是算上復工的時間,長期來看整體的交付周期還是被拉長了,整體還是低效的,而且糟糕的生產質量人很容易打擊開發人員的持續生產高質量代碼的信心,所以將 code review 計入開發的工作量是重視長期利益的一種做法,也是 code review 能夠成功落地的重要前提,從團隊管理的角度來說,不計入工作量的事情就不會被重視,不被重視的話那么 code review 最終在團隊只會被廢棄或者流於應付形式,並未發揮作用。也是很多團隊推行 code review 失敗的原因。
推行 Code Review 的關鍵原則
想要在審核代碼的時候,避免團隊成員因為某些模糊不清的細節爭論不休的情況,那么就要提前讓團隊建立對代碼審核的原則和方法達成共識,我就曾經見過團隊的技術人員在代碼審核的時候因為某個函數方法的實現方式爭吵不休,各自都認為自己的實現是正確的,那么提前建立一下這種共識:
相互尊重原則
站在代碼作者的角度:
- 審核人花費時間和精力閱讀他不熟悉的代碼,並且幫忙指出代碼中的問題來幫助代碼作者提高,代碼作者應該盡可能的為審核人提供配合和方便
- 代碼作者提交高質量的代碼,就是對審核人和審核團隊的最基本尊重(提交一堆亂如麻花的代碼,沒有自測錯誤百出的代碼是極度不負責任的表現)
- 最好要有清晰的 commit 歷史,讓人可以一目了然代碼的提交內容,如果代碼過度復雜,那么就需要和審核人面對面溝通,才能足夠的高效
站在代碼審查者的角度:
- 一定要懂得相互尊重,提出建議要懂得換位思考,考慮代碼作者的感受,不要用主觀的批評或者情緒化的語氣指責團隊的同事
- 提出代碼改進建議,必須是基於事實,或者明確的代碼規范文檔,不可強行把個人喜好強加在對方身上(例如用不同的語法實現相同的功能 for/while )
- 不要鑽進代碼的牛角尖和摳細節,人工審查更多的要把精力放在代碼邏輯,功能設計等無法掃描的問題上
建立共識
站在團隊的角度:
- code review 的目標長期來看,收益是提升團隊的項目質量,減少團隊陷入反復修復 bug 的困境中,讓團隊有機會去面對更多的挑戰
- code review 對個人和團隊而言都是成長的機會,放下不必要的自尊心,要用開放的包容的心態去接受不同的意見,取其精華
總結
以上就是我個人和團隊在 Code Review 中的實踐和總結,Code Review 關鍵還是要結合團隊的情況選擇合適的審查方式,如果團隊追求敏捷開發,快速迭代那么集中式的代碼審查會可能就不太適合你們當前的團隊,可能項目成員 1 對 1 的結對編程可以更加高效的完成代碼審查,每個團隊的發展階段不同,適用的 GitFlow 開發流程也不同,反正沒有最好的工具,最有最合適的工具。