您好,登錄后才能下訂單哦!
關(guān)于Code Review的重要性,我相信好的工程師都能認(rèn)識(shí)到。 參考 "讓Code Review稱(chēng)為一種習(xí)慣" 和 "從Code Review談如何做技術(shù)"。
同時(shí)引用一下有人對(duì)Google Code Review的描述:
The biggest thing that makes Google’s code so good is simple: code review. At Google, no code, for any product, for any project, gets checked in until it gets a positive review.
Code Review 主要Revivew什么
Architecture/Design
單一職責(zé)原則.
這是經(jīng)常被違背的原則。一個(gè)類(lèi)只能干一個(gè)事情, 一個(gè)方法最好也只干一件事情。 比較常見(jiàn)的違背是處理促銷(xiāo)的時(shí)候,同時(shí)處理驗(yàn)券邏輯。
行為是否統(tǒng)一
比如緩存是否統(tǒng)一,錯(cuò)誤處理是否統(tǒng)一, 日志打印是否統(tǒng)一, 方法實(shí)現(xiàn)是否統(tǒng)一等等。
同一邏輯/同一行為 有沒(méi)有走同一Code Path?低質(zhì)量程序的另一個(gè)特征是,同一行為/同一邏輯,因?yàn)槌霈F(xiàn)在不同的地方或者被不同的方式觸發(fā),沒(méi)有走同一Code Path 或者各處有一份copy的實(shí)現(xiàn), 導(dǎo)致非常難以維護(hù)。
代碼污染
使用魔數(shù),例如直接比對(duì)數(shù)字。編寫(xiě)不容易閱讀的代碼,應(yīng)用了很多復(fù)雜的設(shè)計(jì)。
重復(fù)代碼
主要看有沒(méi)有把公用組件,可復(fù)用的代碼,函數(shù)抽取出來(lái)。
Open/Closed 原則
就是好不好擴(kuò)展。 Open for extension, closed for modification.(做好接口設(shè)計(jì)會(huì)很好解決這些問(wèn)題)。
面向接口編程 和 不是 面向?qū)崿F(xiàn)編程
主要就是看有沒(méi)有進(jìn)行合適的抽象, 把一些行為抽象為接口。
健壯性
對(duì)Corner case有沒(méi)有考慮完整,邏輯是否健壯?有沒(méi)有潛在的bug?
有沒(méi)有內(nèi)存泄漏?有沒(méi)有循環(huán)依賴(lài)?(針對(duì)特定語(yǔ)言,比如Objective-C) ?有沒(méi)有野指針?
有沒(méi)有考慮線(xiàn)程安全性, 數(shù)據(jù)訪(fǎng)問(wèn)的一致性
錯(cuò)誤處理
有沒(méi)有很好的Error Handling?比如Price接口出錯(cuò)。
有沒(méi)有增加必要的監(jiān)控,及時(shí)報(bào)警。
改動(dòng)是不是對(duì)代碼的提升
新的改動(dòng)是打補(bǔ)丁,讓代碼質(zhì)量繼續(xù)惡化,還是對(duì)代碼質(zhì)量做了修復(fù)?
效率/性能
兩層循環(huán),數(shù)據(jù)請(qǐng)求量的限制,較大數(shù)據(jù)等耗時(shí)操作是否處理得當(dāng)。
關(guān)鍵算法的時(shí)間復(fù)雜度多少?有沒(méi)有可能有潛在的性能瓶頸。
復(fù)雜需求,是否有必要的設(shè)計(jì), 可預(yù)見(jiàn)的效率問(wèn)題, 開(kāi)發(fā)模式一致性的問(wèn)題 應(yīng)該盡早在Design Review階段解決。如果Design階段沒(méi)有解決,那至少在Code Review階段也要把它找出來(lái)。
Style
可讀性
衡量可讀性的可以有很好實(shí)踐的標(biāo)準(zhǔn),就是Reviewer能否非常容易的理解這個(gè)代碼。 如果不是,那意味著代碼的可讀性要進(jìn)行改進(jìn)。
命名對(duì)可讀性非常重要,我傾向于函數(shù)名/方法名長(zhǎng)一點(diǎn)都沒(méi)關(guān)系,必須是能自我闡述的。
英語(yǔ)用詞盡量準(zhǔn)確一點(diǎn)(哪怕有時(shí)候需要借助Google Translate,是值得的)
函數(shù)長(zhǎng)度/類(lèi)長(zhǎng)度
函數(shù)太長(zhǎng)的不好閱讀。 類(lèi)太長(zhǎng)了,比如超過(guò)了1000行,那你要看一下是否違反的“單一職責(zé)” 原則。
恰到好處的注釋。 但更多我看到比較差質(zhì)量的工程的一個(gè)特點(diǎn)是缺少注釋。
參數(shù)個(gè)數(shù)(不要超過(guò)5個(gè)參數(shù))
Review Your Own Code First
跟著名的橡皮鴨調(diào)試法(Rubber Duck Debugging)一樣,每次提交前整體把自己的代碼過(guò)一遍非常有幫助,尤其是看看有沒(méi)有犯低級(jí)錯(cuò)誤。
如何進(jìn)行Code Review
多問(wèn)問(wèn)題。多問(wèn) “這塊兒是怎么工作的?” “如果有XXX case,你這個(gè)怎么處理?”
每次提交的代碼不要太多,最好不要超過(guò)1000行,否則review起來(lái)效率會(huì)非常低。
當(dāng)面討論代替Comments。 大部分情況下小組內(nèi)的同事是坐在一起的,face to face的 code review是非常有效的。
區(qū)分重點(diǎn),不要舍本逐末。 優(yōu)先抓住 設(shè)計(jì),可讀性,健壯性等重點(diǎn)問(wèn)題。
Code Review的意識(shí)
作為一個(gè)Developer , 不僅要Deliver working code, 還要Deliver maintainable code.
必要時(shí)進(jìn)行重構(gòu),隨著項(xiàng)目的迭代,在計(jì)劃新增功能的同時(shí),開(kāi)發(fā)要主動(dòng)計(jì)劃重構(gòu)的工作項(xiàng)。
開(kāi)放的心態(tài),虛心接受大家的Review Comments。
審核人及職責(zé)分配
所謂職責(zé)歸屬:即指誰(shuí)對(duì)這個(gè)Code負(fù)責(zé)
提交人
審核人
職責(zé)歸屬
P2.1及以下
P2.3
審核人
P2.2及以上
P2.3
提交人&審核人
p2.3及以上
p3.1/p3.2
提交人&審核人
對(duì)于comments的檢查。周會(huì)上抽查。
審核流程
開(kāi)始
RD完成開(kāi)發(fā)自測(cè)
自查不過(guò)
自查通過(guò)
Review your
own code
RD按照comment意見(jiàn)修改
重新自測(cè)并重新提交代碼
是
否
是否可以Merge
Merge至主分支
1.只有主分支權(quán)限的人才能Merge
結(jié)束
是
否
是否需要
代碼走讀
RD發(fā)起Code Review
跟著名的橡皮鴨調(diào)試法(Rubber Duck Debugging)一樣,每次提交前整體把自己的代碼過(guò)一遍非常有幫助,尤其是看看有沒(méi)有犯低級(jí)錯(cuò)誤。
是否走讀標(biāo)準(zhǔn)
1.修改了核心鏈路代碼;
2.修改代碼行數(shù)> 600 行;
3.修改公用業(yè)務(wù)組件或邏輯;
4.審核人提出走讀意見(jiàn);
1.按照要求選擇審核人;
2.設(shè)置PR完成時(shí)間;
3.補(bǔ)充code主要變動(dòng)范圍
4.跟進(jìn)PR完成狀態(tài)
發(fā)起人組織
Code Review會(huì)
stash上同步記錄 commits
否
Review
是否通過(guò)
merge條件:
1.approve >= 2人;
2.comment 都完成修改;
備注標(biāo)簽
流程節(jié)點(diǎn)
分支判斷
圖示例
常見(jiàn)代碼開(kāi)發(fā)規(guī)范
thrift服務(wù)提供一般情況都需要在finally里輸出info級(jí)的入?yún)⒑头祷貐?shù)的日志
實(shí)現(xiàn)Object的toString方法而不是使用json序列化工具輸出日志
Integer的等值使用equals而不是==
使用apache commons 包而不是自己造輪子
組織參數(shù)抽取方法來(lái)完成而不要在service里面寫(xiě),方法命名規(guī)范成buildXXXXX
線(xiàn)程池的使用需要統(tǒng)一到一個(gè)Utils類(lèi)中,避免線(xiàn)程池定義泛濫。
所有遠(yuǎn)程服務(wù)調(diào)用都需要封裝delegate類(lèi),禁止直接使用octo客戶(hù)端進(jìn)行調(diào)用。在真正調(diào)用一般都要finally里輸出info日志 入?yún)⒑头祷刂怠?/p>
靜態(tài)變量需要統(tǒng)一在一個(gè)類(lèi)中定義。
OCTO生成的類(lèi)不要傳遞到service層,構(gòu)造一個(gè)本地類(lèi)進(jìn)行使用。
不要把配置寫(xiě)在代碼里,充分利用MCC和*.properties
MCC里配置開(kāi)關(guān)和頻繁修改的屬性,長(zhǎng)期不修改的放到*.properties
給方法起名字是為了自己和其他人能看懂
變量命名以及方法名不要使用拼音縮寫(xiě)
Json序列化統(tǒng)一使用travel-insurance-common表里的JsonUtils
不要在ThriftService里寫(xiě)業(yè)務(wù)邏輯。下沉service
不要拷貝代碼
執(zhí)行update語(yǔ)句一定要注意 where 條件里 一定要走索引,這句話(huà)的意思是,把where 條件單獨(dú)放一個(gè)select里 然后explain一下,如果是全表掃描 那這個(gè)SQL會(huì)鎖全表。
不要在返回boolean的方法里面寫(xiě)if (xxxxx&xxxx){return true}else{ return false}
永遠(yuǎn)不要在事務(wù)里rpc
拋出異常最好子類(lèi)化,這樣從cat看到異常就知道是啥原因。
邏輯嵌套不要超過(guò)3層
@Transactional(rollbackFor =Exception.class) 使用事務(wù)的時(shí)候 一般情況這么用。
查詢(xún)不要使用mybatis生成的condition來(lái)拼,mybatis生成工具只負(fù)責(zé)生成表的po和最基本的insert 和update ,如果有分表,請(qǐng)所有sql全部手寫(xiě),必須帶分表鍵。
不要在static{}代碼塊里做初始化動(dòng)作,禁止在static{}代碼塊里rpc
免責(zé)聲明:本站發(fā)布的內(nèi)容(圖片、視頻和文字)以原創(chuàng)、轉(zhuǎn)載和分享為主,文章觀(guān)點(diǎn)不代表本網(wǎng)站立場(chǎng),如果涉及侵權(quán)請(qǐng)聯(lián)系站長(zhǎng)郵箱:is@yisu.com進(jìn)行舉報(bào),并提供相關(guān)證據(jù),一經(jīng)查實(shí),將立刻刪除涉嫌侵權(quán)內(nèi)容。