老外的代碼走查
有一篇關(guān)于代碼走查的漫畫疤估,一屋子程序員在一起做代碼走查思灌,在屋子外面的人數(shù)一數(shù) WTF 出現(xiàn)的頻率,大概就知道走查代碼的質(zhì)量水平了舌仍。WTF 可能有點(diǎn)夸張了妒貌,但是這至少說明一件事情——這一屋子程序員至少是真的在審查代碼并對(duì)代碼的水平給出了自己的意見通危。
我們的代碼走查
很難想象我們的代碼走查會(huì)充斥著 WTF 菊碟,因?yàn)槲覀兊拇a走查都很 和諧 。
我經(jīng)歷過的大多數(shù)代碼走查都是這么過來的:開發(fā)人員把代碼寫完并已經(jīng)調(diào)試通過了平匈,然后不管是為了滿足團(tuán)隊(duì)的驗(yàn)收準(zhǔn)則框沟,還是因?yàn)轫?xiàng)目有強(qiáng)制要求,反正找?guī)讉€(gè)同事一起看看增炭,大致流程就是接上投影儀,然后從第一行開始往下念拧晕,這里是在干什么隙姿,那里是在干什么,正常情況下參加走查的同事大概能堅(jiān)持個(gè)十來分鐘不走神厂捞,然后眼神就開始迷茫了输玷,等所有代碼念完靡馁,象征性的提幾個(gè)大小寫或者格式對(duì)齊的問題欲鹏,然后記錄到excel里面,大功告成臭墨。
代碼走查為什么沒有效果
為什么我們的代碼走查這么和諧呢?看起來并沒有起到應(yīng)有的效果红竭?真是讓人百思不得其解的問題。
而在后來和其他的 team leader 溝通時(shí)才發(fā)現(xiàn)原來所有人都有同樣的疑問
為什么代碼走查的效果一點(diǎn)都不好憾股?
帶著這個(gè)問題參加了一場(chǎng)又一場(chǎng)的代碼走查會(huì)議之后往枣,我找到了下面兩個(gè)可以說服我自己的答案:
- 避免沖突:長(zhǎng)期中庸文化熏陶讓我們下意識(shí)的避免沖突,在會(huì)議中指出他人的代碼問題會(huì)讓所有人都不舒服倔叼,多一事不如少一事
- 代碼可讀性不高:即使我們能夠說服所有人相信走查代碼并不是針對(duì)個(gè)人汗唱,并消除掉所有的顧忌,但仍會(huì)因?yàn)榇a本身的問題導(dǎo)致走查的效果不理想
代碼可讀性的問題相對(duì)于中庸之道更加隱蔽丈攒。代碼走查本質(zhì)上就是在讀代碼哩罪,如果代碼的邏輯層次不清晰,命名混亂肥印,依賴復(fù)雜识椰,就會(huì)讓人難以理解,更談不上去發(fā)現(xiàn)隱藏在其中的bug了深碱。不妨將待走查的代碼設(shè)想為一個(gè)小 baby 的玩具房間腹鹉,第一個(gè)房間剛剛經(jīng)歷了熊孩子的大鬧天宮,第二個(gè)房間剛剛被勤勞的媽媽整理收拾干凈敷硅,如果我們的目的是從兩個(gè)房間里找到一件特定物品功咒,我想大多數(shù)人都會(huì)認(rèn)為第二個(gè)房間更加容易。
而且兩個(gè)問題產(chǎn)生的影響還會(huì)疊加——首先绞蹦,演示代碼的同事看起來并不希望有人質(zhì)疑他的設(shè)計(jì)力奋,其次,這些狗屁不通的代碼我完全不知道是在干啥幽七,所以景殷,我還是抽空刷一刷朋友圈吧……
應(yīng)對(duì)之道
一,讓我們不要那么中庸
中庸——這種傳統(tǒng)的東方智慧可以幫助我們?cè)谔幚砗芏嗍虑闀r(shí)得心應(yīng)手,不像西方人那么死板猿挚,但是軟件開發(fā)行為以及衍生出來的技術(shù)和管理實(shí)踐都是根植于西方哲學(xué)(如信息論咐旧、控制論),這種價(jià)值觀的沖突讓東方的程序員在實(shí)施代碼走查之類的實(shí)踐時(shí)出現(xiàn)各種不適應(yīng)绩蜻。
這種不適應(yīng)是無法在短時(shí)間內(nèi)扭轉(zhuǎn)過來的铣墨。我們從出生起就一直在東方哲學(xué)的指導(dǎo)下生活,雖然很少有人意識(shí)到它的存在办绝,但是幾十年的耳濡目染早已深入骨髓伊约。認(rèn)識(shí)的一位管理教練曾經(jīng)說過一句話讓我印象深刻,“改變一個(gè)人是很危險(xiǎn)的孕蝉,但是我們可以改變他所處的環(huán)境”屡律,我想為了讓東方程序員適應(yīng)這些實(shí)踐,大概也只能通過下面這些改變環(huán)境的辦法慢慢來了:
- 營造安全的技術(shù)環(huán)境
明確地聲明代碼集體所有權(quán)會(huì)是一個(gè)好的開始降淮。確保任何人可以修改任何一段代碼疹尾,并且鼓勵(lì)將代碼重構(gòu)的更好的行為,鼓勵(lì)面對(duì)面的方案討論骤肛,避免每個(gè)人負(fù)責(zé)小一塊代碼,避免局部范圍的技術(shù)壟斷窍蓝。當(dāng)尷尬或者負(fù)面情緒出現(xiàn)時(shí)及時(shí)發(fā)現(xiàn)和化解(比如可以重申代碼集體所有權(quán)的原則)腋颠。 - 種子選手的示范作用
在代碼走查會(huì)議中,經(jīng)驗(yàn)豐富且具備強(qiáng)烈責(zé)任性的開發(fā)人員是優(yōu)秀的種子選手吓笙,邀請(qǐng)或鼓勵(lì)他們對(duì)代碼提出自己的看法淑玫,發(fā)起討論,其他人會(huì)自然參與進(jìn)來面睛。 - 讓所有人看到這真的管用
當(dāng)討論發(fā)生后絮蒿,要確保討論形成可以落地的結(jié)論,如果有更優(yōu)的設(shè)計(jì)就堅(jiān)決拋棄掉現(xiàn)有的代碼并按新設(shè)計(jì)進(jìn)行重構(gòu)叁鉴,即使僅僅是提出更準(zhǔn)確的變量命名也應(yīng)該在代碼走查會(huì)議上當(dāng)場(chǎng)重命名土涝。
二,讓代碼具備走查的基礎(chǔ)
心儀的女神到家里做客幌墓,邀請(qǐng)女神參觀房間之前我們肯定會(huì)先收拾一下但壮,同樣的道理,在代碼拿到會(huì)議上進(jìn)行走查之前常侣,我們也要先確保代碼進(jìn)行了初步的收拾蜡饵,比如沒有違反團(tuán)隊(duì)的編碼規(guī)范,檢查了內(nèi)存申請(qǐng)和釋放是否匹配胳施,異常也正確的進(jìn)行了捕獲溯祸,這些動(dòng)作可以通過約定 Check list 來進(jìn)行自檢,避免走查會(huì)議的時(shí)間都浪費(fèi)在這些細(xì)枝末節(jié)的爭(zhēng)論之中。
代碼走查應(yīng)該聚焦于功能實(shí)現(xiàn)的完整性和代碼架構(gòu)的合理性焦辅,關(guān)于第一點(diǎn)本文暫不涉及博杖,代碼架構(gòu)的合理性又由很多因素決定,比如語言氨鹏、架構(gòu)欧募、設(shè)計(jì)模式等等,在《重構(gòu)》一書中 Martin Fowler 整理了很全面的技巧仆抵,在本文中我想重點(diǎn)介紹的是如何控制代碼的邏輯層次來提升代碼的可讀性跟继。
TBD...
三,工具和其他
- 一個(gè)順手而強(qiáng)大的 IDE 可以大大降低重構(gòu)的成本(如 Eclipse)镣丑,讓開發(fā)人員重構(gòu)代碼時(shí)行云流水舔糖,滿滿的成就感油然而生
- 經(jīng)驗(yàn)豐富的會(huì)議主持人,保證代碼走查會(huì)議是在互相尊重的氛圍下進(jìn)行莺匠,確保合理的會(huì)議時(shí)間安排(時(shí)間不宜太長(zhǎng)金吗,根據(jù)走查的代碼靈活安排走查的重點(diǎn))
我們搞敏捷實(shí)踐,不管是 scrum xp KANBAN 精益 趣竣,每一種方法都有一套具體的實(shí)踐摇庙,這些單個(gè)的實(shí)踐之間其實(shí)是有關(guān)聯(lián)關(guān)系的,很少能獨(dú)立存在遥缕,拿代碼走查來說卫袒,如果團(tuán)隊(duì)缺少集體認(rèn)同的代碼規(guī)范,或者對(duì)CleanCode的理解或價(jià)值存在不一樣的認(rèn)知单匣,沒有集體代碼所有權(quán)的意識(shí)夕凝,沒有擁抱變化、互相尊重的心態(tài)户秤,缺少實(shí)現(xiàn)高擴(kuò)展性代碼的能力码秉、重構(gòu)的能力,那么做集體代碼走查就很難做好鸡号。而一旦做不好转砖,團(tuán)隊(duì)反過來就會(huì)質(zhì)疑做這個(gè)事情的意義,一旦我們對(duì)敏捷實(shí)踐開始質(zhì)疑膜蠢,那我們?cè)趯?shí)施的時(shí)候就會(huì)更加隨意堪藐,按《第五項(xiàng)修煉》里的心智模型,這就是一個(gè)典型的正反饋系統(tǒng)挑围,這個(gè)正反饋系統(tǒng)一旦形成礁竞,我們的敏捷轉(zhuǎn)型失敗就只是時(shí)間問題……