知乎上有個問答:大家的公司的 Code Review 都是怎么做的?遇到過哪些問題?很多答主都提到Code Review的作用是提前發(fā)現(xiàn)bug、提高代碼質(zhì)量,順帶統(tǒng)一團隊編碼規(guī)范等等。
秀一下我們的幾次CodeReview。
提前發(fā)現(xiàn)bug
當了爸媽的人都難免有“不讓孩子再吃自己吃過的苦”這樣的想法。其實reviewer也會有這種“老父親/老母親”的心理:“不讓別人再踩自己踩過的坑”。
比如這段討論。為了把一個對象中的字段轉(zhuǎn)為Map(key為字段名、value為字段值),我們有這樣一段代碼:
private Map<String, String> buildBankCreditMap(Bank bankCredit) {
Map<String, String> map = new HashMap<>(70,1L);
map.put("productCode", bankCredit.getProductCode());
map.put("name", bankCredit.getName());
map.put("idNo", bankCredit.getIdNo());
map.put("mobile", bankCredit.getMobile());
map.put("cardNo", bankCredit.getCardNo());
map.put("education", bankCredit.getEducation());
map.put("marriage", bankCredit.getMarriage());
map.put("email", bankCredit.getEmail());
// 后略
return map;
}
圍繞這段代碼,我們有這樣一段review(聊天):
首先,有同事L在review時提出可以用反射來做,并表示在另外的某個地方有現(xiàn)成的代碼可供參考。隨后,另一位同事S微微一笑:“在你來之前我們就用過反射了”,并指出了使用反射可能帶來的問題。同事L恍然大悟,在同事S的明教之下,修改了他的代碼,避免了一個由于對技術(shù)理解不夠透徹而導(dǎo)致的bug。
那是不是只有技術(shù)大牛能夠在review中提前發(fā)現(xiàn)bug呢?顯然不是。除了技術(shù)不足的原因,對業(yè)務(wù)理解不夠也會導(dǎo)致bug。而這種bug同樣可以在“老父親/老母親”的目光下被提前發(fā)現(xiàn)并解決。
例如,某次需求在系統(tǒng)增加了這樣兩個枚舉:
/**
* 新增 75
*/
XXX_SUCCES("XXX_SUCCES",75,75),
/**
* 新增 78
*/
XXX_SIGN("XXX_SIGN",78,78),
關(guān)于這兩行代碼,有這樣一段review:
這段review與技術(shù)無關(guān),它指出的是一個純粹的業(yè)務(wù)bug:這個枚舉所處理的業(yè)務(wù)要求它的構(gòu)造方法中的第一個參數(shù)必須是“xxx.SUCCESS”或者"xxx.FAIL"格式。雖然寫代碼的同事并不熟悉這個業(yè)務(wù)要求,但是好在熟悉業(yè)務(wù)的同事參與了review,并提前發(fā)現(xiàn)了這個bug。
那么,是不是只有精通技術(shù)、或者熟悉業(yè)務(wù),才能參與code review,并發(fā)現(xiàn)潛在的bug呢?其實也不是。我們再看看這段代碼:
private List<BankCardListVO> queryBankCardListVOs(List<BankListDTO> bankListDTOs){
List<BankCardListVO> bankCardListVOs = new ArrayList<>();
BankCardListVO info = new BankCardListVO();
for (BankListDTO bankListDTO : bankListDTOs){
info.setBankId(bankListDTO.getCode());
info.setBankLogo(bankListDTO.getIcon());
info.setBankName(bankListDTO.getName());
bankCardListVOs.add(info);
}
return bankCardListVOs;
}
這里的review簡單明了地指出其中的問題:
這個bug的原因與業(yè)務(wù)無關(guān),也不涉及多么高精尖的技術(shù),純粹就是開發(fā)人員粗心大意造成的。只要認真參與review,就能發(fā)現(xiàn)這種粗心大意、一時手誤的問題。
提高代碼質(zhì)量
提高代碼質(zhì)量、提升開發(fā)技術(shù),應(yīng)該說是每個程序員的目標。實現(xiàn)目標的方式有很多,參與code review就是其中一種。無論是看別人寫的代碼、還是看圍繞代碼展開的討論,都有“他山之石可以攻玉”的作用。
例如,我們有這樣一個類:
/**
* 對原生的 {@link HttpServletRequestWrapper} 做一次包裝,使之可以添加參數(shù)。*
* @author ***
* @date 2019年4月12日
*/
public class RequestParamWrapper extends HttpServletRequestWrapper {
// 略
}
關(guān)于它,我們有這樣一段review(聊天):
看完這段review,是不是對SpringMVC和HttpServletRequest有多了一點了解?如果有興趣再去鉆研一下“SpringMVC其實還有其它方法來實現(xiàn)這個功能”,是不是又能百尺竿頭更進一步了呢?
又如,圍繞Controller是直接操作Response、還是封裝ResponseEntity來返回InputStream,我們也有這樣的review(聊天)。相信無論對三位直接參與者還是眾多圍觀者,這段討論都會大有裨益:
統(tǒng)一團隊規(guī)范
其實個人覺得……統(tǒng)一團隊規(guī)范這個作用在review中算是名列“后”茅的了。但是在實踐中,很多review都是從檢查編碼規(guī)范開始的:命名啦,注釋啦,換行啦,空格啦,等等。有時甚至?xí)o人一種“review就只能檢查檢查代碼規(guī)范”的感覺。
這種感覺當然是錯覺,我們在review中引發(fā)的討論、發(fā)現(xiàn)的bug就是明證。但是,就如張國榮也要苦熬十年一樣,我們也在“review就只能檢查代碼規(guī)范”的泥潭中跋涉了很久。這其實是開展code review的必經(jīng)之路。一方面,從未經(jīng)歷過review的團隊,其代碼規(guī)范肯定存在問題——要么有規(guī)范不遵守,要么壓根沒有規(guī)范。另一方面,對于reviewer來說,規(guī)范問題是最容易被發(fā)現(xiàn)一類問題。這兩方面湊到一起,規(guī)范問題還不一抓一大把么?
要從這個泥潭中走出來,最根本的法子就是團隊真正的建立規(guī)范、遵循規(guī)范、重視規(guī)范。只有做到了這一點,code review才能有效地提前發(fā)現(xiàn)bug、提高代碼質(zhì)量。
聯(lián)系客服