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