八招幫你執行快速代碼審查
譯文【51CTO.com快譯】如果您有過代碼審查的經驗,一定經歷過高頻、耗時且繁瑣的拉取請求、提交確認、以及批準等過程。為了避免凌晨5點,您還在孤獨地審查著從團隊分配來的代碼,我們走訪了該領域的專家與用戶,收集到了如下小貼士,以方便您快速高效地完成任務。
1、審查較小部分
通常而言,更小的提交會導致更小、且更易于管理的代碼審閱。人們往往需要花較長的時間,去理解由大塊代碼的修改所涉及到的大量依賴項。而小塊的修改不僅能夠節省代碼審查的時間,而且能夠減輕審查人員的認知負擔,方便審查過程的流暢開展。可以說,將工作量分成較小的部分,往往可以使團隊成員加深對于變更意圖與方式的了解。
有調查表明:一次性審查約400行代碼的效果是最佳的。否則,過多的代碼量,會直接導致審查者發現問題能力的下降。當然,我們也可以根據實際使用的平臺、以及開發的語言,略作調整。如今大家都在談論“長期主義”。一開始,大家可能會不太適應這種較小的審查提交方式,但是如果能長此以往地堅持下去,它的好處將非常明顯。
2、時限要求
與代碼測試相比,代碼審查環節往往被要求在有限的時間內完成并提交。為了能夠及時地發現代碼本身、及其架構和時序等相關問題,審查人員往往需要對代碼具有充分的了解。因此,在這種“時間緊、任務急”的情況下,團隊需要對待代碼的審查重點排定優先級。例如,我們可以針對如下方面,根據實際情況進行審查:
- 條件判斷語句或其他邏輯是否合理?
- 代碼中的字符串是否已格式化?
- 是否在不必要之處使用了同步或鎖的操作?
- 是否采用了原子變量?
- 是否使用了不必要的線程,且是否安全?
- 數據結構是否安全且高效?
根據上述要點,我們整理出一份審查清單(下文將會提到),以方便團隊合理地安排時間與精力。當然,即使在項目進度緊迫,無法進行完全代碼審查的情況下,我們也需要保證新的、關鍵性的、具有依賴關系的代碼部分,能夠被審查到。
3、對事不對人
代碼審查講求的是以”對事不對人”的態度,全面提高代碼的質量。例如:倘若甲發現了乙的代碼中存在著問題,這并不意味著甲的編程能力強,而乙的能力弱。我們更不能據此去懲罰乙(當然,獎勵甲是應該的)。否則,甲可能因為害怕破壞了與團隊中其他成員的關系,而不愿在審查中指出真實潛在的問題,進而導致代碼的審查效果失真。
此外,有些團隊會將代碼審查的任務集中在某個專人身上。這樣除了會造成人員安排上的單點風險以外,還會造成其工作量上的繁重和認知度上的局限性。
4、共享編碼與審查準則
既然不合適將代碼審查任務固定地托付給一個人,那么我們勢必要構建一個團隊或小組。而為了保證集體智慧“在線”,我們需要讓所有參與者都事先了解相關的審查準則。例如:
- 規范化針對代碼添加的注釋,闡明代碼修改的原因,以方便后續者的解讀。
- 修正編碼風格,尤其是一些關鍵性的數據結構、以及方法的命名規則。
- 審查是否充分考慮到了變量或異常可能出現的所有情況。
當然,對于不同的編程語言與平臺,我們可以采取略有不同的編碼與審查準則,并記錄在案。下面是在社區里被廣泛采用的代碼樣式標準。它們可以促進和加速新的成員,在代碼風格上盡快地融入團隊。
- Ruby - http://www.caliban.org/ruby/rubyguide.shtml
- Community-driven - https://github.com/bbatsov/ruby-style-guide
- Github’s style - https://github.com/styleguide/ruby
- SO Answer - http://stackoverflow.com/questions/616037/ruby-coding-style-guidelines
- Rubydoc - http://ruby-doc.com/docs/ProgrammingRuby/
- Javascript - https://google-styleguide.googlecode.com/svn/trunk/javascriptguide.xml
- Crockford’s guide - http://javascript.crockford.com/code.html
- Felix’s Node style - https://github.com/felixge/node-style-guide
- Mozilla - https://developer.mozilla.org/en-US/docs/JavaScript_Tips
- Idiomatic.js - https://github.com/rwaldron/idiomatic.js
- Python - http://google-styleguide.googlecode.com/svn/trunk/pyguide.html
- Guido’s PEP8 - http://legacy.python.org/dev/peps/pep-0008/
- python-guide.org - http://docs.python-guide.org/en/latest/writing/style/
- PHP - https://developer.wordpress.org/coding-standards/wordpress-coding-standards/php/
- Pear - https://dev.topear/
- PHP-FIG - http://www.php-fig.org/
- PSR-0: Autoloader Standard - https://github.com/php-fig/fig-standards/blob/master/accepted/PSR-0.md
- PSR-1: Basic Coding Standard - https://github.com/php-fig/fig-standards/blob/master/accepted/PSR-1-basic-coding-standard.md
- PSR-2: Coding Style Guide - https://github.com/php-fig/fig-standards/blob/master/accepted/PSR-2-coding-style-guide.md
5、審查清單
常言道,“按圖索驥,效率最高”。我們可以參考如下清單,來逐條檢查并提高代碼審查的流程與效率。
編程習慣方面
- 是否刪除了每行代碼尾部的多余空格。
- 是否存在從未被用到的變量。
- 是否針對變量、方法、以及類采用了相同的命名規則。
- 對于括號、循環、if語句等是否采用了統一的格式。
- 是否將常量寫在了獨立的常量類中。
- 是否針對不同的異常(exception),采用了不同的捕獲(catch)語句。
- 是否避免了單個方法過于冗長。
- 為了避免一條語句過長,且超過編輯工具的可視區域,是否按需對其進行了拆分。
- 是否給各種方法添加了適當的訪問控制,而非一律采用public。
- 是否合理地用到了靜態工廠方法,而非重載構造函數。
功能方面
- 如果某個邏輯會被多次使用到,那么就應該將它寫成幫助類或是API,以便被頻繁調用。
- 不同語言的代碼不應被相互混用。例如,在JSP中就不應包含Java代碼。
安全方面
- 任何代碼在未經轉義之前,都不應直接執行用戶的輸入。例如JavaScript中的eval函數,以及SQL語句。
- 在代碼級別上,禁止那些在較短時間內,被大量提交的IP請求。
- 是否為每個類、變量、以及方法都設置了正確的訪問域。
性能方面
- 是否能及時地關閉不需要的數據庫實例、以及文件的操作句柄。
- SQL語句的用法是否規范。
- 是否按需創建了immutable的類。
- 是否避免使用了heavy對象。
- 是否將全局信息保存在“application context”中。
文檔方面
- 是否說明了代碼中的每一個類、方法、及其基本邏輯。
- 是否提供了針對復雜的HTML、JavaScript、以及CSS等相關文檔說明。
- 是否為代碼文件的頭部添加了相關的版權信息。
- 如果是對某個缺陷的修復,是否分配了對應的缺陷ID。
與此同時,您可以參考諸如:DRY、SRP、KISS、YAGNI、Smell等原則, 以及如下三種審查清單模板:
- http://www.codeproject.com/Articles/593751/Code-Review-Checklist-and-Guidelines-for-Csharp-De
- http://courses.cs.washington.edu/courses/cse403/12wi/sections/12wi_code_review_checklist.pdf
- https://www.liberty.edu/media/1414/%5B6401%5Dcode_review_checklist.pdf
6、使用自動化協同審查工具
在處置Git存儲庫里的頻繁提交等場景時,光靠一雙眼睛式的人工審查方式,顯然是非常低效且耗時的。為了發揮團隊的優勢,我們需要引入協同審查工具,以實現更快速、更自動化、更全面的合作式審查。目前,Github、Bitbucket和GitLab都能夠通過拉取式請求的特性,提供內置的代碼審查工作流。當然,我們也可以用到諸如:CheckStyle、PMD、FindBugs、Upsource、以及Codacy等工具。
7、使用短路
如果您時間非常緊迫,并且無法去逐行檢查代碼的內容,那么請采用“抓大放小”漸進的方法。畢竟,那些在函數調用時可能引起緩沖區溢出的問題,以及在生產環境中會導致程序崩潰的潛在缺陷,比起一眼可以看出的代碼樣式問題,要重要得多。您可以在代碼檢查中,插入所謂短路(short-circuiting)元素,以事先處置和糾正重大的問題,而將較小的缺陷,留待將來時間充沛時,再予以更正。
8、提交與確認
從某種意義上說,代碼審查旨在提高開發者的編程能力,讓其從自身犯過的錯誤中吸取教訓,從他人的修改思路中學習進步,而應當避免其產生抵觸或反感情緒。
值得注意的是,代碼審查人員不應以交付時限為由,針對其發現的問題,直接對代碼進行修改,甚至予以重構,而應當提請代碼開發人員進行確認。此方法不但可以確認問題是否真實存在,并共同獲取最佳解決方案;而且可以讓代碼作者深入了解其自身的不足,協助其不斷進步。作為參考,您可以通過鏈接--https://www.kernel.org/doc/Documentation/SubmittingPatches,借鑒一下Linux內核是如何指導其開發社區進行問題的提交與處置的。
原文標題:Top 10 Ways to Perform Fast Code Reviews,作者:Gustavo Silva
【51CTO譯稿,合作站點轉載請注明原文譯者和出處為51CTO.com】