敏捷開發(fā):中國十八年目睹之怪現(xiàn)狀
持續(xù)交付領(lǐng)域?qū)<覇塘豪蠋熓且粋€(gè)好人,他講話特別委婉。喬老師說:“你不改變你的工作方式就不能得到 10 倍的效果。”大家聽了這個(gè)話以后就覺得,他講的是一個(gè)抽象的“人群”。每個(gè)人聽到這個(gè)話以后都有一個(gè)自我暗示:喬老師說的是其他人,我不包含在內(nèi)。因?yàn)樗呛萌?,他不肯把話說得太直白。其實(shí)喬老師批評(píng)業(yè)內(nèi)敏捷現(xiàn)狀的話,說直白了就是斷水流大師兄的話:“我不是針對(duì)你,我是說在座各位……”
當(dāng)然這個(gè)現(xiàn)狀不完全是你們?cè)斐傻?。臺(tái)下的各位大部分還很年輕,這些現(xiàn)狀形成的歷史因素很可能你們還不了解。我今天分享的就是這些行業(yè)歷史的故事。
中國 IT 行業(yè)的發(fā)展不是自然而然的。有人認(rèn)為,經(jīng)濟(jì)自然發(fā)展到一定的程度就自然會(huì)推動(dòng)信息科技的發(fā)展。不是這樣的。有一個(gè)反例就擺在面前,香港現(xiàn)在的 IT 行業(yè)就非常糟糕,經(jīng)濟(jì)的發(fā)展并沒有自然而然地推動(dòng)香港 IT 的發(fā)展。IT 是一個(gè)非常高端的行業(yè),它不是自然就會(huì)發(fā)展起來,它需要政府有相當(dāng)大的主導(dǎo)意向。
因“18 號(hào)文件”而興起的中國 IT 業(yè)
大家可以查一下 2000 年 6 月頒布的國務(wù)院 18 號(hào)文件《鼓勵(lì)軟件產(chǎn)業(yè)和集成電路產(chǎn)業(yè)發(fā)展的若干政策》,中國的 IT 行業(yè)完全是這個(gè)發(fā)文推動(dòng)起來的,其中給了這個(gè)行業(yè)很多的優(yōu)惠政策,很多政策直到今天仍然在推動(dòng)這個(gè)行業(yè)的發(fā)展。
在“18 號(hào)文件”頒布之前,2000 年的時(shí)候,中國 IT 行業(yè)從業(yè)人員大概是十幾萬人,是一個(gè)很小的行業(yè)。到 10 年以后,這個(gè)人群發(fā)展到了數(shù)百萬人。這個(gè)發(fā)展的速度,人的大腦本能理解不了。我們可以做個(gè)對(duì)比:中國的經(jīng)濟(jì)發(fā)展也是很快的,每年 10% 左右;當(dāng)時(shí)政府的預(yù)測(cè)是 IT 行業(yè)可以有每年百分之十幾的增長,超過 GDP 增速。但是實(shí)際上,從 2000 年以后的 10 年,IT 行業(yè)保持了每年 50% 以上的增長,這是“放火箭”一樣的發(fā)展,超出所有人的理解能力。在 10 年的時(shí)間從業(yè)人數(shù)增加了數(shù)十倍,這對(duì)整個(gè)行業(yè)來說是一個(gè)巨大的考驗(yàn)。
很快,這個(gè)行業(yè)就遇到了挑戰(zhàn):軟件質(zhì)量差、交付進(jìn)度難以保障,等等。這種現(xiàn)象大家很熟悉,軟件工程的教材上講過,這個(gè)叫軟件危機(jī)。當(dāng)時(shí)專家的意見是:為什么會(huì)出現(xiàn)軟件危機(jī),是因?yàn)榧夹g(shù)環(huán)節(jié)不過關(guān),社會(huì)化大生產(chǎn)沒有形成,解決的辦法就是要提高軟件工程水平。
這是 2001 年的行業(yè)大背景。當(dāng)時(shí)的行業(yè)對(duì)軟件工程有一種非常迫切的需求。于是那個(gè)時(shí)候,行業(yè)就去引進(jìn)了 CMM。
以 CMM 為代表的軟件工程理論準(zhǔn)確識(shí)別軟件開發(fā)的基本功
2001 年,我給《程序員》雜志社采訪了號(hào)稱“CMM 始祖”的一個(gè)印度人。CMM 在 2001 年左右傳入中國,非常明確給中國軟件行業(yè)指出了問題所在。它非常清楚地指出軟件開發(fā)應(yīng)該具備哪些基本的能力:需求管理,項(xiàng)目管理,配置管理,質(zhì)量保障等。這些能力就是 CMM 二級(jí)里面定義的,大家回頭找 CMM 二級(jí)來看一下就知道了。從這個(gè)角度來說,CMM 是一個(gè)非常有價(jià)值的框架。
國家對(duì) CMM 做了很多的補(bǔ)貼。當(dāng)時(shí)科技部主導(dǎo),從北京市開始各地都有相應(yīng)的補(bǔ)貼政策:通過 CMM 二級(jí)認(rèn)證補(bǔ)貼 20 萬,三級(jí) 30 萬,五級(jí) 50 萬。
十八年后,行業(yè)的基本功扎實(shí)了嗎?
有這么好的政策在這兒,十八年以后,我們行業(yè)的基本功補(bǔ)齊了嗎?我們行業(yè)的基本功扎實(shí)了嗎?
我覺得這個(gè)事情不能用非常抽象的方式來講,我來講幾個(gè)真實(shí)的“鬼故事”。
需求管理?
比如說需求管理我可以講個(gè)故事。2009 年、2010 年的時(shí)候,我當(dāng)時(shí)在很著名的某家通信企業(yè)指導(dǎo)一個(gè)項(xiàng)目,當(dāng)時(shí)跟華為的兩個(gè)系統(tǒng)工程師去客戶那調(diào)研需求。去之前這兩位工程師說:“你不知道,我們這個(gè)客戶是妖怪,沒事兒就罵我們,動(dòng)不動(dòng)就改需求,特別的可怕。”我說我去看一下吧,了解一下這個(gè)妖怪的客戶都是怎么回事兒。
約到客戶上午 9 點(diǎn)鐘開始調(diào)研需求,我們幾個(gè)人走過去,這兩位系統(tǒng)工程師上去:“你好,現(xiàn)在你有什么需求,請(qǐng)告訴我們。”后來我看《人民的名義》那個(gè)片,我就聯(lián)想起這兩位系統(tǒng)工程師調(diào)研需求的場景,他走到那兒把手一伸:“請(qǐng)開始你的表演。”然后客戶就開始講,一上午三個(gè)小時(shí),客戶大概講了 2 小時(shí) 58 分鐘,兩個(gè)系統(tǒng)工程師講了可能不到 10 句話,包括“你好”、“請(qǐng)開始你的表演”、“謝謝”。
然后需求調(diào)研就完了,中午的時(shí)間寫會(huì)議紀(jì)要,寫完以后給客戶發(fā)出去,20 分鐘以后客戶打電話過來開始罵人,整個(gè)辦公室都聽見了:“你們做的是什么需求調(diào)研?我一早上給你講了 3 個(gè)小時(shí),講了 5 個(gè)要點(diǎn),你郵件紀(jì)要發(fā)過來只有 3 個(gè)要點(diǎn),你浪費(fèi)我一早上時(shí)間逗我玩嗎?”
這個(gè)就是我們行業(yè)里面很領(lǐng)先的企業(yè)調(diào)研需求的方式。類似的行為我后來看到過很多次,大家去“調(diào)研需求”到底是干什么?就是走去:“客戶爸爸你好,請(qǐng)問你有什么需求,請(qǐng)你告訴我。”這樣調(diào)研需求,需要什么技能、需要什么專業(yè)能力?什么都不需要。這個(gè)就是人類本能好嗎?“我想知道一件事,請(qǐng)你告訴我可以嗎?”這個(gè) 6 歲小孩也會(huì)。從這些現(xiàn)象里,我后來總結(jié)出來一個(gè)概念叫做“全憑本能工作”。我們這個(gè)行業(yè)里有很多本來應(yīng)該是專業(yè)人士做的專業(yè)工作,實(shí)際上是全憑本能在做,看不到專業(yè)的能力。
項(xiàng)目管理?
說完需求管理我們?cè)賮碚f項(xiàng)目管理。我們這個(gè)行業(yè)的項(xiàng)目管理到底是怎么做?你找一個(gè)項(xiàng)目經(jīng)理來問,你的項(xiàng)目管理是怎么做的?他能跟你講很多大道理。但你到軟件開發(fā)的現(xiàn)場里面去,到項(xiàng)目組里面待個(gè)兩星期,你看看項(xiàng)目管理到底怎么發(fā)生的。真實(shí)的情況經(jīng)常是這樣:
項(xiàng)目經(jīng)理走過來問:“你這個(gè)任務(wù)哪天可以完成?”
開發(fā):“下個(gè)禮拜一吧。”
項(xiàng)目經(jīng)理:“下個(gè)禮拜一?這個(gè)時(shí)間太長,禮拜五能不能完成?”
開發(fā):“不行,這工作量太大了。“
項(xiàng)目經(jīng)理:“就禮拜五,我們禮拜五就上線了。“
開發(fā):“好吧,禮拜五就禮拜五,我加個(gè)班,挑戰(zhàn)一下!“
是不是我們真正的項(xiàng)目管理就是這樣發(fā)生的?你說這個(gè)項(xiàng)目管理,到底管理什么?真實(shí)項(xiàng)目里的工作量評(píng)估是怎么估的?
開發(fā)說:“做這個(gè)要 5 天。“
項(xiàng)目經(jīng)理:“憑什么要 5 天,明明 2 天就做完了。“
開發(fā):“那 3 天吧。“
這是項(xiàng)目管理嗎?這是賣白菜。
配置管理?
然后我們?cè)賮碚f配置管理。我以前做一個(gè)持續(xù)集成的咨詢項(xiàng)目,我先非常自信地把代碼庫 check out 出來,然后我去打一杯咖啡回來再看看。打完咖啡,發(fā)現(xiàn)還沒有 check out 完,那我再去開個(gè)會(huì)。開完會(huì)回來看看,還沒有 check out 完,那我再去吃個(gè)午飯。吃完飯回來看看,還沒有 check out 完,我就納悶了。
我:你們這個(gè)代碼庫怎么這么久還沒有 check out 完呢?
客戶開發(fā):你自己在 check out?,我們都不這么干,我們都是從別人那里拿一個(gè)移動(dòng)硬盤拷過過來。
我:你代碼庫多大?
客戶開發(fā):代碼庫有 5 個(gè) G……
后來我拿一個(gè)移動(dòng)硬盤把代碼拷過來一看,這個(gè)代碼庫有 5 個(gè) G,上面有一千多個(gè)分支。這就是 CMM 五級(jí)的企業(yè)的配置管理水平。很多故事我都不好意思說,鬼故事講出來嚇?biāo)廊恕?/p>
質(zhì)量管理?
接著我們?cè)僬f說質(zhì)量保障。為什么現(xiàn)在行業(yè)里面大家搞迭代,周期都是兩個(gè)禮拜一個(gè)版本,成了行業(yè)共識(shí)? 因?yàn)槎际且粠蜏y(cè)試小姑娘跟著屁股后面做人肉測(cè)試,你怎么敢繼續(xù)縮短呢?你縮短到一個(gè)禮拜發(fā)一個(gè)版本,然后小姑娘就得每個(gè)禮拜天天加班。這就是我們這個(gè)行業(yè)里的質(zhì)量保障水平。
所以,像我這種工作時(shí)間長的人就非常好奇。我 2001 年就看見了當(dāng)時(shí)搞 CMM 的時(shí)候,有很多的培訓(xùn)公司講課,然后政府又有補(bǔ)貼,通過 CMM 的公司非常多。那這個(gè)事情到底是怎么跑偏的?為什么大家搞了十幾年的 CMM,到現(xiàn)在行業(yè)里面的能力是這樣的,各個(gè)公司都是全憑本能在工作?前兩天有一個(gè)群里有人說:“我們公司的研發(fā)管理做減法,不寫文檔了,做完減法之后我們非常敏捷。”我說你們從來就沒有研發(fā)管理,做的什么減法呢?你們有一堆文檔,但是文檔跟真正發(fā)生的研發(fā)根本就是兩碼事,實(shí)際上的研發(fā)就是大學(xué)實(shí)驗(yàn)室的工作方法,大家全憑本能在工作。
軟件工程是如何跑偏的?
那么軟件工程到底是什么時(shí)候跑偏的呢?我去年寫《敏捷中國史》的時(shí)候看了很多的材料,然后發(fā)現(xiàn)很多的事情是從根子上跑偏的。一開始,很多專家把軟件的生產(chǎn)和制造業(yè)相關(guān)聯(lián)。但是非常有趣,盡管這些中國軟件工程專家經(jīng)常講制造業(yè),但是他們對(duì)制造業(yè)根本不懂,他們根本不知道這個(gè)制造業(yè)是怎么發(fā)展。
1995 年左右,美國里海大學(xué)亞科卡學(xué)院受國防部的委托,做了一個(gè)叫做《21 世紀(jì)制造業(yè)挑戰(zhàn)》的研究,這個(gè)研究報(bào)告里講 21 世紀(jì)的制造業(yè)有什么特征?是需要高度的定制化、高度的柔性,需要減小批量。聽著像什么?像敏捷。而我們國家的軟件工程專家們根本不了解制造業(yè)的這些新發(fā)展。他們?cè)谀X子里面自己想象了一個(gè)“制造業(yè)”,然后說我們的軟件工程應(yīng)該像制造業(yè)。他們想象的制造業(yè)是少數(shù)的精英在上面做設(shè)計(jì)、下面有大量的軟件藍(lán)領(lǐng)把精英的設(shè)計(jì)一模一樣的寫出來就完了。
基于這么一個(gè)模型,他們就開始搞培訓(xùn),要求程序員踏踏實(shí)實(shí)搞工作,不要去想別的,不要去跟需求方打交道,這就是軟件藍(lán)領(lǐng)。而同一時(shí)期,美國的制造業(yè)在說:不應(yīng)該嚴(yán)格區(qū)分設(shè)計(jì)和制造,不應(yīng)該限制員工思考的空間。這些專家想象的制造業(yè),跟制造業(yè)的發(fā)展方向根本南轅北轍。
CMM 是如何跑偏的
那么 CMM 明明已經(jīng)提出了很好的問題,為什么這個(gè)問題沒有得到解決?國內(nèi)軟件專家的誤解呢,只能說他的知識(shí)不夠多,不知道國外的軟件和制造業(yè)到底是怎么樣的發(fā)展,所以有了自己的想象。而 CMM 我認(rèn)為很大程度上是個(gè)人品問題。從最早的“CMM 始祖”Ron Radice 開始,CMM 周圍就一直有這種人品問題。
這個(gè)號(hào)稱 CMM 始祖的人 2001 年到中國來訪問,我當(dāng)時(shí)參加了對(duì)他的采訪。當(dāng)時(shí)總共有 5 家媒體對(duì)他做了采訪,宣傳做得到處都是。我后來做了對(duì)這個(gè)人比較深入的調(diào)查,他是在發(fā)明 CMM 的研究小組里面一個(gè)研究員,他大概只發(fā)表過 2 篇論文,沒有什么重要的學(xué)術(shù)著作。他在 CMM 的創(chuàng)始過程當(dāng)中只能說起到了非常輔助的作用。據(jù)說印度的總理專門接見了他,我起碼花了 5、6 個(gè)小時(shí)的時(shí)間嘗試去找到這么一個(gè)接見的報(bào)道,沒有任何結(jié)果,我認(rèn)為這是編造出來的。
我覺得這個(gè)人非常有象征意義:CMM 從傳入中國的第一年開始就充滿了編造、吹捧、虛假、欺騙。2002 年的時(shí)候,這種現(xiàn)象已經(jīng)引起 SEI 的關(guān)注了。SEI 認(rèn)為一家企業(yè)在一年時(shí)間里從 CMM 二級(jí)過到五級(jí),這是不可能的事情。而這個(gè)不可能的事情在中國 2002 年、2003 年連續(xù)發(fā)生了三次。所以當(dāng)時(shí) SEI 自己開始撇清關(guān)系了,就說我們認(rèn)為這是非常不可能的。
這么不可能的任務(wù),這些公司是怎么做到的?非常簡單,叫做裁判下場踢球。非常簡單的一個(gè)邏輯:公司想要這個(gè)認(rèn)證,找誰做咨詢?這個(gè)咨詢師就是未來的評(píng)估師。咨詢師收了你 10 萬以后,然后他自己做的咨詢,他自己回頭再來評(píng)估,當(dāng)然評(píng)估就通過了。就是一個(gè)很簡單的玩法。那么企業(yè)為什么要花這個(gè) 10 萬來請(qǐng)這個(gè)咨詢師?因?yàn)橛姓a(bǔ)貼。政府會(huì)補(bǔ)貼你 20 萬通過二級(jí)。所以就成為了一個(gè)完整的利益輸送鏈,咨詢師、主任評(píng)估師和企業(yè)聯(lián)手搞一個(gè)認(rèn)證通過,就可以從政府那兒掏錢出來,企業(yè)白拿一個(gè)證,從政府那套的錢比它自己花的經(jīng)費(fèi)還多。這是一個(gè)完整的利益輸送鏈。
我經(jīng)常講,“18 號(hào)文件”做了很多的好事情,但是其中的一件事情做的非常糟糕而且匪夷所思,就是對(duì) CMM 的補(bǔ)貼。對(duì) CMM 的政策補(bǔ)貼,這是中國改革開放史上前所未有的事情,不知道以后會(huì)不會(huì)有來者。前所未有在什么地方?中國改革開放史上有很多的產(chǎn)業(yè)補(bǔ)貼,比如對(duì)光伏的補(bǔ)貼,對(duì)大數(shù)據(jù)的補(bǔ)貼,對(duì)出口創(chuàng)匯的補(bǔ)貼,但是這些補(bǔ)貼政策至少都有一個(gè)出發(fā)點(diǎn),就是你得做東西,對(duì)吧?你要領(lǐng)光伏的補(bǔ)貼,你得做出光伏來。你要領(lǐng)出口創(chuàng)匯的補(bǔ)貼,你得出口創(chuàng)匯。而對(duì) CMM 的補(bǔ)貼是中國改革開放史上僅有的一個(gè):你這個(gè)企業(yè)什么都不用干,不用開發(fā)軟件,不用有收入,不用提升團(tuán)隊(duì)的能力,就可以領(lǐng)補(bǔ)貼。這是一個(gè)非常奇怪的政策。在這個(gè)政策的鼓勵(lì)下,CMM 全國到處一片瘋,所有的企業(yè)都去搞這個(gè)事情,因?yàn)槭强梢再嶅X的。這就是政策補(bǔ)貼之下的亂象。因?yàn)橛辛诉@個(gè)政策補(bǔ)貼,搞 CMM 的全是騙子,沒有一個(gè)例外。現(xiàn)在,我經(jīng)常跟搞 Scrum 認(rèn)證的這些朋友在打交道,我跟他們開玩笑說你們搞 Scrum 幸運(yùn)就幸運(yùn)在沒有什么補(bǔ)貼,沒有補(bǔ)貼就不怎么招騙子。所以搞 CMM 的全是騙子,你們搞 Scrum 的不全是騙子。
一線的實(shí)踐者在干什么
CMM 咨詢師在騙錢的時(shí)候, 一線的實(shí)踐者在做什么?在一線干活的這些人是真正感受到了非常迫切的對(duì)軟件基礎(chǔ)能力的訴求,所以是有一些人在干一些很扎實(shí)的事情。
林星當(dāng)時(shí)在廈門國際銀行做項(xiàng)目經(jīng)理,他在 2001 年發(fā)表的幾篇文章,很大程度上講的就是極限編程里面用戶故事這一部分的內(nèi)容。
另一個(gè)極限編程的先行者石一楹 2001 年的時(shí)候在杭州,他是國內(nèi)最早翻譯跟重構(gòu)相關(guān)內(nèi)容的技術(shù)作者。他發(fā)表了這個(gè)系列文章以后,我看到這些文章覺得非常的激動(dòng),其中對(duì)于代碼的理解、對(duì)代碼的質(zhì)量和美感的追求,對(duì)我來說是一個(gè)很重要的啟蒙。后來我知道,他是看了《重構(gòu)》這本書以后,從里面提取的內(nèi)容。我后來翻譯《重構(gòu)》這本書,和石一楹給我的啟蒙是有很大的關(guān)系。我看了他的文章以后非常受鼓舞,就在《程序員》雜志上做了《重構(gòu)》的技術(shù)專題,后來又做了極限編程一系列的文章。
2002 年時(shí)候,人民出版社引進(jìn)了極限編程系列叢書,這是中國第一本關(guān)于敏捷的圖書,這本書直到今天去看還是非常有價(jià)值的。
唐東銘這個(gè)同學(xué)他其實(shí)是一個(gè)相當(dāng)傳統(tǒng)的軟件工程改進(jìn)的這么一個(gè)人。他后來在 18 年的職業(yè)生涯當(dāng)中,沒有真正的做過敏捷的項(xiàng)目。人生的機(jī)緣巧合就是這么難以預(yù)料,他最早引進(jìn)敏捷的書,可是一直沒有得到機(jī)會(huì)去做敏捷的項(xiàng)目。
當(dāng)時(shí)中興有幾個(gè)人,包括鄧輝、孫鳴他們,對(duì)敏捷非常有想法。鄧輝 2003 年翻譯出版了《敏捷軟件開發(fā)》這本書,我翻譯的《重構(gòu)》也是 2003 年出版的。這些敏捷的基礎(chǔ)理論的準(zhǔn)備基本上 15 年前就已經(jīng)完成了。直到現(xiàn)在,很多人問我這個(gè)問題怎么解決、那個(gè)問題怎么解決,我拿出來的答案都是 15 年前的書。
十八年來唯一真正抓基本功的方法
18 年來,行業(yè)里有很多的方法來來去去,真正可以抓軟件開發(fā)的基本功、真正可以提升軟件團(tuán)隊(duì)的能力的方法,我覺得就只有極限編程。CMM 提出的這些核心能力,只有極限編程真正提供了。
一件事應(yīng)該怎么做,你在書上看到一個(gè)說法,和你真正在工作上能做這件事,是相差很大的。
再比如項(xiàng)目管理,極限編程會(huì)告訴你迭代怎么去管,根據(jù)什么來看項(xiàng)目的進(jìn)度。當(dāng)然項(xiàng)目管理這一部分,我認(rèn)為 Scrum 也是很好的,非常有效地告訴大家項(xiàng)目管理的方法。
再說配置管理。到底什么是配置管理?其實(shí)配置管理落到根本上就是持續(xù)集成。有持續(xù)集成,你就有有效的配置管理;沒有有效的持續(xù)集成,就是沒有配置管理,就是這么簡單的事情。沒有持續(xù)集成,你可以說在紙面上有很多配置管理的流程,但真到了需要軟件的時(shí)候你怎么辦?你只能依賴一個(gè)配置管理員來手工打包。越是你著急需要打包軟件的時(shí)候,這個(gè)人就越出錯(cuò)、越是打不出包來。好不容易打出來的包一測(cè)有問題,然后大家一起加班。所以我說配置管理很簡單,你有持續(xù)集成、每天可以有一個(gè)候選版本通過持續(xù)集成打出來,你就有配置管理;出不來,你就沒有配置管理。
那為了讓持續(xù)集成有效,最后的最后一切都會(huì)落到重構(gòu)和單元測(cè)試上面。是不是擁有高覆蓋率的、可靠的、運(yùn)行快速的單元測(cè)試,這是一個(gè)決定性的分水嶺。而高覆蓋率的、可靠的、運(yùn)行快速的單元測(cè)試集,得到這個(gè)東西最有效的辦法,就是測(cè)試驅(qū)動(dòng)開發(fā),就是你必須先寫測(cè)試、再寫實(shí)現(xiàn),你才可能得到這么一個(gè)有效的測(cè)試集。有很多人跟我講,我們先趕緊寫完了實(shí)現(xiàn),回頭再去補(bǔ)單元測(cè)試。“寫完實(shí)現(xiàn)再去補(bǔ)單元測(cè)試”,這個(gè)鬼故事,我每年都聽十幾次,你們誰見它真正發(fā)生的?我們經(jīng)常聽到這個(gè)對(duì)話:
領(lǐng)導(dǎo):單元測(cè)試很重要,我們要寫單元測(cè)試。
開發(fā):好好好,等我改完這個(gè)版本我就補(bǔ)單元測(cè)試。
改完了這個(gè)版本就有空了嗎?有空了還有下一個(gè)版本呢。你在寫代碼的時(shí)候根本沒有考慮怎么單元測(cè)試,為什么你認(rèn)為寫完實(shí)現(xiàn)代碼以后就可以補(bǔ)上測(cè)試了?你補(bǔ)不上。你會(huì)對(duì)著一大堆草率堆上去的代碼長嘆一口氣,因?yàn)槟阋婚_始寫代碼的時(shí)候就沒考慮代碼的可測(cè)試性。
這件事情我覺得非常有趣:軟件工程的教科書里面都寫著,單元測(cè)試是軟件開發(fā)的重要環(huán)節(jié)。所有人都認(rèn)同單元測(cè)試的價(jià)值,但是誰也不做。然后到了實(shí)踐里面,大家說我寫完這個(gè)版本我就補(bǔ)單元測(cè)試,然后這個(gè)版本完了之后沒有補(bǔ),然后下一個(gè)版本來了之后又說,我寫完這個(gè)版本就補(bǔ)單元測(cè)試,下一個(gè)版本做完也沒有補(bǔ)。這種現(xiàn)象使我對(duì)于人類作為一個(gè)整體的學(xué)習(xí)能力非常擔(dān)憂,因?yàn)榇蠹覜]有從歷史中學(xué)習(xí)的能力:補(bǔ)單元測(cè)試這個(gè)事情是從來沒有發(fā)生過的,所以未來它也不會(huì)發(fā)生,這才是合理的。你根本就不應(yīng)該相信“我做完這個(gè)版本補(bǔ)單元測(cè)試”這種話。
所以一切的一切最后都會(huì)歸結(jié)到有沒有有效的單元測(cè)試集。得到有效的單元測(cè)試集最直接的辦法,叫做測(cè)試驅(qū)動(dòng)開發(fā)。我翻譯《重構(gòu)》第二版的時(shí)候跟另一個(gè)譯者林從羽開玩笑說,你告訴任何一個(gè)敏捷實(shí)施當(dāng)中遇到的問題,我都可以告訴你這個(gè)問題是因?yàn)闆]有做好 TDD。
Scrum 為何僵尸化?
比如說前段時(shí)間有人發(fā)明了一個(gè)詞叫“僵尸 Scrum”,什么意思?大家早上開晨會(huì)的時(shí)候都低著頭無精打采的:“我昨天在做這個(gè)任務(wù),我今天繼續(xù)做這個(gè)任務(wù),我沒有什么問題。”就跟一群僵尸一樣的,毫無生氣。你們都見過這個(gè)現(xiàn)象吧?為什么會(huì)有僵尸 Scrum?因?yàn)槊總€(gè)人的任務(wù)、每個(gè)人負(fù)責(zé)的代碼,是一塊一塊隔開的,誰跟誰都沒有關(guān)系。那為什么要把開發(fā)一個(gè)個(gè)隔開呢?因?yàn)檎l也不敢改別人的代碼,別人的代碼看也看不懂,看懂也不敢改,改了也不知道有沒有引入 Bug。為什么別人的代碼看不懂、不敢改、改了不知道有沒有破壞功能?因?yàn)闆]有單元測(cè)試嘛!為什么沒有單元測(cè)試?因?yàn)槟銢]有 TDD 嘛!
這就是個(gè)例子。我半開玩笑說,你告訴我任何一個(gè)跟敏捷實(shí)施相關(guān)的問題,我都能給你推導(dǎo)出來,是因?yàn)槟銢]有 TDD。但是這個(gè)邏輯太繞,太曲折,很難跟人講通。我昨天在一個(gè)敏捷群里面又跟人吵架。我說我的標(biāo)準(zhǔn)非常簡單,有 TDD 的敏捷就是好敏捷,沒有 TDD 的敏捷就是偽敏捷。再多的邏輯我都懶得跟他們講了。郭德綱有一個(gè)話,說一個(gè)外行跑去跟火箭科學(xué)家說你們火箭的燃料不行,得燒煤,還得是精煤,水洗的不行,那科學(xué)家要是拿正眼看他一眼都輸了——我就輸了,那群里的“敏捷專家”連代碼都不會(huì)寫,我還跟他講 TDD。
持續(xù)交互、研發(fā)云、微服務(wù)、DevOps...
再往后就有了很多新的方法,持續(xù)交互、研發(fā)云、微服務(wù)、DevOps......,每一波我都經(jīng)歷過。每一波新方法流行,就會(huì)有客戶來問我對(duì)這個(gè)有什么看法。每一次他們來找我問的時(shí)候,我發(fā)現(xiàn)他們要解決的都是同一個(gè)問題。這個(gè)問題就是軟件開發(fā)的質(zhì)量很差、速度很慢。然后就開始想各種辦法繞過這個(gè)問題。
比如說微服務(wù)流行那年,大家想的是:如果說開發(fā)一個(gè)單體應(yīng)用質(zhì)量很差、開發(fā)很慢,那我們是不是可以把單體應(yīng)用拆分成若干個(gè)微服務(wù),每個(gè)人負(fù)責(zé)一小塊微服務(wù),然后就可以對(duì)質(zhì)量的要求沒有那么高?最后發(fā)現(xiàn),還是不行。一波一波的浪潮過去,看多了之后,我終于明白一個(gè)很簡單的道理。最后決定開發(fā)的質(zhì)量和效率的是什么?是持續(xù)集成,是持續(xù)集成里面運(yùn)行的測(cè)試集的效率和質(zhì)量。你可以得到一個(gè)高效率、高質(zhì)量的測(cè)試集,你就能做好軟件。沒有高效率、高質(zhì)量的測(cè)試集,軟件開發(fā)的效率和質(zhì)量就不會(huì)好。
于是我們又回到這兒來了。大家一波一波的嘗試解決同一個(gè)問題,但是從來不去解決這個(gè)問題的核心,都在繞著問題走,都在想可以用什么樣的流程和工具去解決問題,就是不敢直面核心的問題:我的人基本功不行,我們不會(huì) TDD。一次一次去繞,一次一次繞不開。《敏捷宣言》第一句怎么說?人和交互重于流程和工具。但是搞敏捷的公司在做什么?十幾年了,一次一次想用流程和工具解決人和交互不行的問題。
以前我做咨詢的時(shí)候,我必須要為了項(xiàng)目的需要、為了公司收入的需要去配合這些客戶,跟他們一起想辦法,用流程和工具稍微緩解一下問題?,F(xiàn)在我不做咨詢了,我終于可以說實(shí)話了:這個(gè)核心問題繞不開,沒有辦法。軟件開發(fā)的質(zhì)量和效率不行的問題,它就是一個(gè)人和交互的問題:“人”就是個(gè)人能力的問題,“交互”就是團(tuán)隊(duì)能力的問題。人的能力和團(tuán)隊(duì)的能力不提升,基本功沒有扎實(shí),用什么樣的工具都解決不了這個(gè)問題。
沒有基本功,什么花哨套路都白搭
軟件做不好,就是因?yàn)椴恢涝趺撮_發(fā)。沒有基本功,什么花哨的套路都玩不了,玩到最后你都會(huì)面臨同樣的一個(gè)問題:我今天在這兒改一行代碼,我怎么知道改完以后整個(gè)系統(tǒng)到底是不是好的?怎么回答這個(gè)問題,是決定性的分水嶺。如果你沒有一套完備、可靠、快速的測(cè)試集,那么回答這個(gè)問題唯一的辦法就是改完這行代碼然后叫測(cè)試部的小姑娘來回歸測(cè)試。但是測(cè)試部的小姑娘她會(huì)很反感老是這么人肉回歸,她就會(huì)打我。她打了我之后,我下一次不敢隨便找她了,于是我就多攢一堆修改再去找她:“姐姐,給我一起回歸一下唄。”現(xiàn)實(shí)就是這樣的,軟件開發(fā)的周期就是這么被拖長的。沒有 TDD,你就解決不了這個(gè)問題。所以軟件開發(fā)的核心問題,不管講 DevOps 也好,講持續(xù)交付也好,最終都得回到極限編程這里來。
之前有大概幾年的時(shí)間,我對(duì)這個(gè)信念產(chǎn)生了懷疑:我說極限編程是不是太難了?是不是不適合這個(gè)行業(yè)?其實(shí)細(xì)想想這個(gè)說法也挺不好的。當(dāng)我說“是不是極限編程不適合這個(gè)行業(yè)”的時(shí)候,我心里面想的是:在座的各位智商是不是有點(diǎn)不足,所以你們掌握不了極限編程?但我覺得實(shí)際情況不是這樣。我覺得大家都是有這個(gè)能力的。所以我重新堅(jiān)定了信念。
回到極限編程,回到軟件開發(fā)基本功
今年不是講“不忘初心、牢記使命”嗎,我現(xiàn)在重新找回了我的初心和使命:極限編程是正確的,極限編程是真正有效的軟件開發(fā)方法。所以我們一幫朋友把極限編程的中文網(wǎng)站做出來了。網(wǎng)站做出來以后非常的有效:別人問我很多軟件開發(fā)方法和管理方法的問題,我直接從極限編程網(wǎng)站找一段,截一個(gè)圖甩過去,很多問題直接就可以解答。
同時(shí),我想證明一件事情:極限編程沒有那么難,它不是在座各位不可以掌握的,它不是一個(gè)有著巨高的智力門檻的事情,它是所有人都可以掌握的。為了證明這件事情,我到現(xiàn)在為止開了 5 期的極限編程的練功房,每一期幾百人,到現(xiàn)在為止大概有 2000 人在我的練功房里面學(xué) TDD,學(xué)重構(gòu)。事實(shí)證明這些東西不是學(xué)不會(huì)的,還不會(huì)的這些同學(xué)缺的就是刻意練習(xí),你沒有動(dòng)手去練而已。
基本功的提升辦法只有一個(gè):刻意練習(xí)
什么是刻意練習(xí)?
刻意練習(xí)有三個(gè)要素。
第一是大量的重復(fù)練習(xí)。你在書上看到一個(gè)東西,不等于你就會(huì)了這個(gè)技能??赐陼院竽憧赡芸梢愿I(lǐng)導(dǎo)去白活兩句,面試的時(shí)候可以吹一吹,但是你肯定不會(huì)。這個(gè)技能,你在工作中用不出來,這個(gè)就是不會(huì)。要掌握一個(gè)技能,就必須要練,必須要大量重復(fù)的練習(xí)。
第二,要在學(xué)習(xí)區(qū)去練習(xí)。那就需要有人來設(shè)計(jì)練習(xí)的節(jié)奏,設(shè)計(jì)每天該練什么。大家可以去看 Kent Beck 的《測(cè)試驅(qū)動(dòng)開發(fā)》那本書,非常好的一本書,由淺入深循序漸進(jìn)的。但是很多人看那本書,一上來就被打懵,根本看不下去。為什么?我做了這些培訓(xùn)之后才知道,很多人自己的電腦上開發(fā)環(huán)境沒有準(zhǔn)備好,JUnit 測(cè)試怎么寫、怎么運(yùn)行都不知道。所以一定要有人給你設(shè)置每天練習(xí)的目標(biāo),給你拆解每天該練什么、掌握什么技能,才能一步步練下去。
第三是要有及時(shí)的反饋。有人告訴你今天練得對(duì)不對(duì)。在這些練功房的培訓(xùn)里面,我看到跑偏的太多了,跑偏的方式千奇百怪。所以必須有人看到,這個(gè)同學(xué)今天這個(gè)練習(xí)是跑偏了,然后要告訴他正確的練習(xí)方法是什么樣子的,他才會(huì)有所進(jìn)步。
做了這些練功房的培訓(xùn)以后,我最近開始反思另外一個(gè)問題:我們這個(gè)行業(yè)里面的培訓(xùn)、知識(shí)付費(fèi),這些東西到底在干嘛?我前兩天跟另外一個(gè)知識(shí)付費(fèi)的平臺(tái)談合作,他說他們的課程是以音頻為主,要給學(xué)員聽聲音。我就好奇了,什么場景下大家需要一個(gè)音頻為主的學(xué)習(xí)方式呢?他說,比如說我們學(xué)員早上開車的時(shí)候就可以聽這個(gè)課,晚上睡覺之前可以抱著手機(jī)聽一節(jié)課。你早上開車的時(shí)候聽一節(jié)課可以學(xué)到什么有效的知識(shí)?你什么都學(xué)不到。你只能獲得一種幻覺,這個(gè)幻覺叫做“我今天早上開車的時(shí)候?qū)W到知識(shí)了”。
所以我突然之間發(fā)現(xiàn),這個(gè)行業(yè)里面大量的知識(shí)付費(fèi)都是騙子,因?yàn)樗緵]有讓你掌握一個(gè)技能。比如說我舉個(gè)例子,吳恩達(dá)的機(jī)器學(xué)習(xí)的課,你如果不去做他的練習(xí),你就看一遍他的視頻,甚至于更糟糕的,你聽一遍他的音頻,你可以學(xué)會(huì)機(jī)器學(xué)習(xí)嗎?不可能的。你一定要反復(fù)練習(xí),要有人告訴你練習(xí)的效果,你才會(huì)學(xué)到東西。那這些知識(shí)付費(fèi)到底在干嘛?這個(gè)問題非常的困擾。
包括線下的培訓(xùn)也一樣。線上培訓(xùn)的采購是這么一個(gè)邏輯:學(xué)員給老師打分,然后采購培訓(xùn)的這個(gè)人根據(jù)學(xué)員的評(píng)分來看老師的水平怎么樣。那學(xué)員怎么給老師評(píng)分?如果老師拿一個(gè)教鞭逼著學(xué)員好好練,練不好一鞭子打下去,你覺得學(xué)員會(huì)給老師打高分嗎?不會(huì)的。學(xué)員打高分就是這個(gè)老師講得很好,講得很風(fēng)趣,老師穿插了很多的游戲,寓教于樂,我就給老師打高分。結(jié)果我們看到現(xiàn)在的企業(yè)培訓(xùn)是一個(gè)什么場景?老師恨不得在臺(tái)上表演:“培訓(xùn)是一門語言的藝術(shù),講究說學(xué)逗唱……”這不是在學(xué)本事,這是小劇場聽相聲呢。那我們這個(gè)行業(yè)到底變成了一個(gè)什么行業(yè)?是一個(gè)傳授人技能的行業(yè)還是說相聲的行業(yè)?
所以,我現(xiàn)在不做這種音頻、視頻的知識(shí)付費(fèi)了,現(xiàn)在開練功房就是學(xué)員們進(jìn)來,我設(shè)計(jì)好了每天的練習(xí)任務(wù),學(xué)員自己練,自己反思,練完了拿出代碼來我點(diǎn)評(píng)。人就是得反復(fù)練,才能養(yǎng)成新的習(xí)慣。