代碼審查(code review)是指對源代碼進行系統(tǒng)化地審查,是軟件開發(fā)中的最佳實踐之一,代碼合并之前必須審查通過才行,可及時發(fā)現(xiàn)隱藏問題,提高代碼質量。
1 為什么要代碼審查
代碼審查環(huán)節(jié),或者流于形式,或者根本沒有,軟件質量只依賴事后的測試;認真執(zhí)行是有諸多價值的。
統(tǒng)一編碼規(guī)范
審查代碼風格,統(tǒng)一編碼規(guī)范,有助于代碼的可讀性,也方便接盤者快速上手。
提前發(fā)現(xiàn)缺陷
代碼審查最直接的優(yōu)點是發(fā)現(xiàn)軟件邏輯問題,性能等等潛在風險,提前發(fā)現(xiàn)缺陷可以有效節(jié)省人力和時間。
提高代碼質量
代碼審查與優(yōu)化修復,確保代碼在健壯性、設計合理性、代碼結構等方面持續(xù)提升整體質量。
知識分享
每一次的代碼審查都是一次知識的分享,磨合一定時間后,軟件設計融合集體的智慧,團隊內相互審查,也是互相學習的一種途徑。
團隊共識
經(jīng)過討論與交流逐步達成的團隊共識,特別是對架構理解和設計原則的認知,在共識的基礎上團隊也會更有凝聚力,軟件設計方式會趨于一致,特別是在較多新人加入時尤為重要。微信公眾號【嵌入式系統(tǒng)】提醒,一些建議性的共識《代碼的保養(yǎng)》。
2 代碼審查原則
如果變更可提升整體代碼質量,就可以讓它通過,即使還不完美,這是代碼評審準則的最高原則。沒有完美的代碼,只有更好的代碼。評審者不應強求代碼提交者在每個細節(jié)都寫得很完美,應該考量修復時間與修改重要性之間的平衡。
以客觀的技術數(shù)據(jù)為準,而非個人偏好。在代碼排版樣式上,遵從編碼規(guī)范,所有代碼保持風格一致,但如果新奇代碼在編碼規(guī)范未提及,那就接受作者的樣式。同時有多種可行方案時,如果作者能證明這些方案基本差不多,那就接受作者的選擇;否則,應以軟件設計原則為準(參考《嵌入式軟件設計原則隨想》),而不應由評審者的個人喜好來決定。微信公眾號【嵌入式系統(tǒng)】提醒,編碼規(guī)范可以參考《嵌入式C編碼規(guī)范》。
如果沒有參考規(guī)則,那么評審者應該保證新代碼與當前軟件庫風格一致,至少不會惡化軟件的質量,一旦惡化就會帶來破窗效應,導致軟件質量逐漸下降。
代碼審核者應該看什么
命名:變量、函數(shù)等命名是否清晰易懂?
注釋:核心代碼的注釋是否都一目了然?
代碼排版:所有的代碼是否都遵循編碼規(guī)范?
設計:代碼是否設計良好?是否適合當前系統(tǒng)?有沒兼容舊版或預留擴展接口?
功能:代碼實現(xiàn)的行為與需求是否相符?
復雜性:代碼可以更簡單嗎?如果由其他開發(fā)者接手,能否很快理解嗎?
文檔:開發(fā)者是否同時更新了相關文檔?
推行代碼審查機制,開發(fā)流程上專門有這個環(huán)節(jié),代碼必須審核通過才可以提交。審核結果或記錄公開透明,團隊內互相審查其他人的代碼,甚至明確考評和代碼審查表現(xiàn)相關,這樣就能落實代碼審查制度。
3 怎么做代碼審查
3.1 作為代碼提交者
發(fā)起時機:軟件變更發(fā)布前提交代碼審查申請。
代碼行數(shù):提交代碼行數(shù)最好在500-1000行以下(非有效代碼除外),一個高質高效的代碼審查最好控制在一個小時以內。
3.2 作為代碼評審者
主要從代碼邏輯和質量兩方面來評審。
代碼邏輯
功能完整:代碼實現(xiàn)是否滿足需求,有沒理解偏差。
邏輯設計:是否符合軟件框架,功能細節(jié)處理是否考慮邊界條件和并發(fā)控制。
數(shù)據(jù)安全:是否存在數(shù)據(jù)安全隱患,參數(shù)篡改或丟失。
性能隱患:是否存在損害性能的隱患,如死循環(huán)等。
測試用例:單元測試用例的驗證邏輯是否有效,測試用例的代碼行覆蓋率和分支覆蓋率。
代碼質量
編碼規(guī)范:命名、注釋、架構分層、軟件排版等是否符合編碼規(guī)范。
可讀性:是否邏輯清晰、易理解,避免使用奇淫巧技。
簡潔性:是否有重復可簡化的復雜邏輯,代碼復雜度是否過高。
可維護性:是否分層清晰、模塊化合理、高內聚低耦合、遵從基本設計原則。
可擴展性:是否僅滿足本次需求,是否有必要的擴展設計。
可測試性:代碼是否方便寫單元測試及分支覆蓋,是否便于自動化測試
3.3 評審注意事項
溝通是至關重要的,團隊要始終保持溝通,并在整個過程中保持透明度,代碼審查提供清晰的反饋修復建議。同時,要記住反饋應該集中在批評代碼本身,而不是代碼的作者。盡快完成評審,避免過度追求完美,抓住重點,水至清則無魚。
4 代碼審查避免流于形式
代碼審查失去意義,主要是審核與否不影響流程,或者時間緊迫必須保證項目進度,或者審核結果修改建議無法執(zhí)行。一旦認為審查是可有可無,后續(xù)就越發(fā)流于形式。
時間與進度的矛盾
項目壓力大時間緊,以致草草分析不做設計,直接編碼不做重構,前期快了最后總要有誰來背鍋。
每次代碼審查的建議都是一次技術交流,但是審查后,發(fā)現(xiàn)問題太多,或者改動太大,影響項目計劃,理論上要求編碼前設計評審方案,實際工作可能是發(fā)布前審查,為了項目進度只能認可既定事實。
或者代碼審查的力度不夠,只能提出一些淺表的問題,建議無非是一些格式、注釋、命名之類不痛不癢的問題,草草了事,這個現(xiàn)象其實更為普遍。
評審者不了解業(yè)務和代碼
代碼提交人需編寫清晰的修改描述,必要的情況下評審者應熟悉需求,否則,脫離功能實現(xiàn)無法發(fā)現(xiàn)真正的邏輯問題。
反饋建議未修改
這一點極為重要,需要對修改后的代碼再次審查,確保理解一致,問題建議有被接受執(zhí)行。
代碼審查耗費人力
代碼審查可能很耗時,特別是處理大型代碼庫或復雜變更時,評審人員需要花費時間和精力仔細審查代碼,這可能會影響整體的開發(fā)速度和項目進度。代碼審查需要多個團隊成員的參與,包括作者和評審人員。這可能對團隊資源產生負擔,特別是在人員有限的組織中。
5 小節(jié)
程序員的智慧結晶都盡在代碼之中,而代碼審查是打磨它更加的純潔無瑕、精致完美,這也值得大家一起持續(xù)精進,即使實際存在諸多阻礙。關于編碼技術路,路漫漫其修遠兮,吾將上下而求索。