從零開(kāi)始 Code Review
這篇帖子不是通篇介紹Code Review的方法論, 而是前大段記錄了我們團(tuán)隊(duì)怎么從沒(méi)有這個(gè)習(xí)慣到每天都進(jìn)行review的過(guò)程, 后小段給出了我的一些建議. 希望能對(duì)諸位的團(tuán)隊(duì)有所幫助.
最初來(lái)到這個(gè)新組建的團(tuán)隊(duì)是木有code review的. 頭說(shuō), 這個(gè)月你來(lái)搞吧.
當(dāng)我***次知道必須得搞review的時(shí)候, 其實(shí)我是拒絕的! 因?yàn)槲矣X(jué)得…呀…你不能叫我馬上搞立馬搞, ***, 我要試一下, 我又不想說(shuō)…團(tuán)隊(duì)之前就沒(méi)有這個(gè)習(xí)慣. 我搞了以后, 那個(gè)耽誤每天的工作時(shí)間啊. 結(jié)果同事一定會(huì)罵我, 給他們?cè)黾宇~外的工作量. 我說(shuō)先讓我嘗試嘗試. 現(xiàn)在呢…每天都在review!每天都在review呢…我還推廣到了其他團(tuán)隊(duì)!來(lái)!來(lái)!來(lái)!大家試試看!
覺(jué)得困難, 開(kāi)展不起來(lái), 想拒絕的原因有很多:
團(tuán)隊(duì)成員寫(xiě)完需求就不管了, 沒(méi)有code review意識(shí)
技術(shù)氛圍不強(qiáng)
水平參差不齊
沒(méi)有合適的工具
…
但是總的來(lái)說(shuō)就是一條, 木有code review. 如果已經(jīng)有了, 無(wú)論是真的在搞, 還是形式主義, 主持一下都是不難的.
從零到一, 從無(wú)到有總是困難的, 咱開(kāi)始了若干次嘗試之路:
***次嘗試
最初的版本是其他團(tuán)隊(duì)的寫(xiě)的, 到我們團(tuán)隊(duì)接手的時(shí)候, 啥都木有. 什么逗號(hào)等號(hào)左右不空格, 類(lèi)名首字母小寫(xiě), 方法名首字母大寫(xiě); 依賴(lài)亂七八糟; 在view里寫(xiě)業(yè)務(wù), 在view里發(fā)網(wǎng)絡(luò)請(qǐng)求. 看到這樣的代碼我當(dāng)時(shí)心里是崩潰的.
我先嘗試一個(gè)人幫整個(gè)團(tuán)隊(duì)review. 零散看了幾天, 問(wèn)題代碼貼了幾十張ppt, 槽點(diǎn)太多, 看起來(lái)很感人. 后來(lái)自己放棄了.
結(jié)論
Code Review 一個(gè)人扛N個(gè)人的代碼是不可取的.
第二次嘗試
結(jié)對(duì)編程可以看做是一種敏捷化的Code Review. 直接結(jié)對(duì)會(huì)被頭劈死. 于是我想著踩用新的結(jié)對(duì)編程方式.
兩位程序員新成結(jié)對(duì)小組, 每人一臺(tái)電腦, 坐在臨近的工位上, 兩人合作完成一組功能(可以是兩個(gè)或多個(gè)獨(dú)立的模塊)的設(shè)計(jì), 代碼實(shí)現(xiàn). 但對(duì)已某一個(gè)模塊來(lái)說(shuō)設(shè)計(jì)和代碼是分開(kāi)的, 一個(gè)人負(fù)責(zé)設(shè)計(jì), 另一個(gè)人負(fù)責(zé)寫(xiě)代碼, 對(duì)于其他模塊則反之.
當(dāng)我在團(tuán)隊(duì)里尋找可以結(jié)對(duì)的伙伴的時(shí)候, 發(fā)現(xiàn)木有可以設(shè)計(jì)模塊, 項(xiàng)目進(jìn)度又差不多, 可以結(jié)對(duì)的小伙伴.
結(jié)論
Code Review需要接地氣.
第三次嘗試
第三次嘗試, 我想用一個(gè)游戲的方法去開(kāi)展review
每次的review主持輪流當(dāng), 由大伙推舉當(dāng)前找得bug最少的同學(xué)來(lái)主持.
每輪開(kāi)始的時(shí)候,先貼出代碼來(lái), 由下面的同學(xué)說(shuō)問(wèn)題.(大伙這個(gè)時(shí)候關(guān)注下哪位同學(xué)次次都木有發(fā)現(xiàn)問(wèn)題)
***由主持的同學(xué)將所有的問(wèn)題列出來(lái).
進(jìn)入下一輪
如果經(jīng)常是下面的同學(xué)說(shuō)的比主持人多,主持人第二天繼續(xù).
主持的同學(xué),每日最少準(zhǔn)備6張問(wèn)題ppt斷.
指出的問(wèn)題由主持人來(lái)指定一個(gè)修改的同學(xué)修改.
第二天的主持人負(fù)責(zé)把當(dāng)天得bug錄入jira, 并且負(fù)責(zé)跟蹤這些修復(fù).
太理想化了, 根本開(kāi)展不起來(lái).
結(jié)論
不要自己覺(jué)得好就是好, Code Review是團(tuán)隊(duì)的事情, 方案定了得拿出去溜溜.
第四次嘗試
無(wú)奈之下, 我去請(qǐng)教我的頭, 如何去開(kāi)這個(gè)頭. 頭就給了兩個(gè)字: 強(qiáng)壓.
于是小伙伴們便在我的淫威之下開(kāi)展了***次的code review. 我用的是之前***次整理出的ppt. 效果竟然好的意外. 小伙伴們互相吐槽被我指出來(lái)的渣渣代碼, 氣氛很是歡樂(lè).
不過(guò)關(guān)鍵問(wèn)題還是沒(méi)有一個(gè)統(tǒng)一的標(biāo)準(zhǔn)去改. 于是咱緊接著就安排了一場(chǎng)代碼規(guī)范的分享. 再接下來(lái)的一次review, 大貨吐槽的點(diǎn)就相對(duì)集中了.
結(jié)論
Code Review初期需要有標(biāo)準(zhǔn). 讓小伙伴們?nèi)绾稳eview.
第五次嘗試
由于之前的氛圍很好, 有小伙伴A提議拿出他負(fù)責(zé)的模塊來(lái)集體review. 有主動(dòng)的, 當(dāng)然不能拒絕. 后面幾天安排的都是review他的模塊了. 順帶還做了一次他的模塊的設(shè)計(jì)分享.
在有天的review中, 有個(gè)小伙伴B表示這樣現(xiàn)場(chǎng)重構(gòu)不是他擅長(zhǎng)的. 我們: 那你擅長(zhǎng)啥? 小伙伴B: 我擅長(zhǎng)xxx. 我: 那下周你來(lái)給大貨分享下吧. 小伙伴B: 好, 我準(zhǔn)備一下.
結(jié)果小伙伴B深藏不漏, 連續(xù)分享了一整個(gè)系列.
結(jié)論
聞道有先后, 術(shù)業(yè)有專(zhuān)攻, 不要低估你的小伙伴們.
第六次嘗試
我被掛的任務(wù)是code review, 所以偶爾還是會(huì)看看小伙伴們代碼的. 有天突然發(fā)現(xiàn)有個(gè)小伙伴C, 在重構(gòu)優(yōu)化代碼了. 咱順勢(shì)和他說(shuō)了一些編程方面的思想和技巧, 告訴他還可以這么重構(gòu), 用查表發(fā)代替條件語(yǔ)句, 用多態(tài)代替提條件語(yǔ)句, 用runtime生成方法名, 用runtime 執(zhí)行方法. 于是他也出來(lái)一個(gè)技術(shù)分享. 可惜的是關(guān)于編程思想的分享討論起來(lái)就木有那么激烈了, 這個(gè)只能慢慢來(lái)了. 不過(guò)當(dāng)咱吃完飯快8點(diǎn)回到公司的時(shí)候, 發(fā)現(xiàn)有兩個(gè)小伙伴DE在寫(xiě)demo, 在討論之前C的技術(shù)分享.
結(jié)論
編程的思想需要慢慢悟, 不能一股腦的灌.
第七次嘗試
有次review, 我有事提前走了. 但是呢, 本是半個(gè)小時(shí)分享大伙覺(jué)得還不盡興, 又延長(zhǎng)了二十分鐘. 之前有幾場(chǎng)分享, 也都不是我主持的. 后續(xù)的review我將嘗試進(jìn)一步淡化我的主持. 讓我們的review可以自組織的進(jìn)行下去.
結(jié)論
Code Review需要達(dá)到理想的狀態(tài) - 不需要我也能自如地運(yùn)轉(zhuǎn), 不然***就會(huì)輪為政治任務(wù).
后記
隨著團(tuán)隊(duì)的人數(shù)增多, 集體review這種方式也會(huì)做出調(diào)整, 我們會(huì)引入一些code review的方法論和工具. 萬(wàn)事開(kāi)頭難, 既然已經(jīng)開(kāi)了這個(gè)頭, 我相信后續(xù)的調(diào)整也不是什么難事.
建議
如何做出從零開(kāi)始code review呢, 我的建議是:
tech leader 強(qiáng)壓所有人開(kāi)始 code review, 這是最重要的一步
安排一次編碼規(guī)范的技術(shù)分享
前期經(jīng)?;仡? 這次的code review開(kāi)展的怎樣, 有哪些地方可以改善
對(duì)于積極的同學(xué)表示鼓勵(lì), 支持現(xiàn)場(chǎng)重構(gòu)代碼
每天不光可以review代碼, 也可以安排整場(chǎng)的技術(shù)分享