這是一份遲到的小結(jié)奴饮,去年底組織完Global Code Retreat后烧给,有些新的感受想要分享。結(jié)果一路拖延下來(lái)缝龄,又多了兩次道場(chǎng)活動(dòng)的收獲。分別是3月份與亞光一起組織的上海敏捷社區(qū)道場(chǎng),和4月底哈羅單車的內(nèi)部活動(dòng)叔壤。再次印證了當(dāng)初的想法瞎饲。
最初組織Coding Dojo的想法
一開(kāi)始我是在公司內(nèi)部組織的。主要原因是那時(shí)候剛剛通過(guò)個(gè)人練習(xí)炼绘,在掌握TDD上有所突破嗅战。因此非常興奮,想要通過(guò)一起練習(xí)的方式把我學(xué)到的東西傳達(dá)給其他人俺亮。
基于這個(gè)出發(fā)點(diǎn)驮捍,活動(dòng)的形式大概是這樣的:
- 首先進(jìn)行了一次內(nèi)部分享,來(lái)講解TDD相關(guān)的概念脚曾,和具體的做法东且。
- 為了讓參與者有直觀的感受,第二次活動(dòng)是展示形式的本讥。由我演示用TDD一步步完成一個(gè)題目珊泳。
- 后面幾次的活動(dòng)是用MOB形式,一臺(tái)連接投影儀的電腦拷沸,大家輪流上來(lái)寫幾分鐘色查。旁邊的人一起討論分析。這樣既可以保證整個(gè)過(guò)程采用了TDD的方式堵漱,又給了每個(gè)體驗(yàn)思考的機(jī)會(huì)综慎。
-
在大家對(duì)TDD都比較熟悉之后,嘗試了結(jié)對(duì)分組形式勤庐,每?jī)扇艘唤M用一臺(tái)電腦示惊,同時(shí)寫一道題目。然后留一段時(shí)間輪流review代碼愉镰。
面臨的挑戰(zhàn)
看起來(lái)是費(fèi)了一些心思逐步推進(jìn)吧米罚?活動(dòng)的實(shí)際效果也確實(shí)不錯(cuò)。不過(guò)丈探,讓更多人掌握TDD這個(gè)目標(biāo)录择,卻沒(méi)有達(dá)到預(yù)期效果。
那么面臨的挑戰(zhàn)是什么呢碗降?
- 首先TDD是需要付諸實(shí)踐的技能隘竭,所以單純的宣講作用是不大的。只講紅讼渊,綠动看,重構(gòu)循環(huán)的話,幾句話就說(shuō)完了爪幻。講得更深的話菱皆,沒(méi)有實(shí)踐也很難體會(huì)到须误。
- 現(xiàn)場(chǎng)演示呢,實(shí)話說(shuō)壓力還是很大的仇轻。眾目睽睽之下腦子很容易短路京痢。為了效果和面子不免要做充分練習(xí),但是這樣又有一些副作用篷店。
- 太熟練了容易講得太快祭椰,聽(tīng)眾跟不上。
- 太熟練也會(huì)讓人覺(jué)得只是這道題目的這種解法練習(xí)的次數(shù)多疲陕,所以才這么遛吭产。對(duì)于方法本身還是持懷疑態(tài)度。
- 然后是輪流MOB的形式鸭轮。每對(duì)輪換上來(lái)的人面臨的心理壓力和單獨(dú)演示是一樣的,還要理解前面一組的思路橄霉。所以往往有手忙腳亂窃爷,焦頭爛額的情況。此外各組也可能思路有差異姓蜂,無(wú)法有步驟的分解解決問(wèn)題按厘。這時(shí)
- 如果努力引導(dǎo),把思路帶回引導(dǎo)者自認(rèn)為“正確”的路上钱慢。一來(lái)影響了每個(gè)人的參與度逮京,也會(huì)讓人覺(jué)得是不是僅僅因?yàn)槟阕鲞^(guò)一遍知道答案了而已。二來(lái)束莫,也不一定就能引導(dǎo)回來(lái)不是懒棉。??
- 自由探索的話,一般來(lái)說(shuō)由于思路反復(fù)和適應(yīng)新方法的過(guò)程览绿。往往在限定時(shí)間內(nèi)進(jìn)度是很有限的策严。雖然對(duì)于我來(lái)說(shuō)這是意料中的情況,但是是否會(huì)打擊初學(xué)者的信心就不得而知了饿敲。
- 最后結(jié)對(duì)同時(shí)進(jìn)行妻导,期待是分別練習(xí)前面的收獲。不過(guò)由于上面提到的一些困難怀各,往往實(shí)際上手進(jìn)行時(shí)發(fā)現(xiàn)還有些點(diǎn)沒(méi)有掌握倔韭,不免卡在某一步。由于分組的方式瓢对,難以充分討論每組的詳細(xì)過(guò)程和困惑寿酌。
所以一段時(shí)間的操練之后,發(fā)現(xiàn)大家對(duì)活動(dòng)本身是比較滿意的沥曹,但是卻遠(yuǎn)未達(dá)到學(xué)會(huì)TDD的目標(biāo)份名。
意料之外的收獲
由于工作調(diào)整等原因碟联,去年相當(dāng)一段時(shí)間沒(méi)有再組織道場(chǎng)活動(dòng),直到最近這三次僵腺。
這次由于對(duì)于對(duì)后續(xù)活動(dòng)難以有很多規(guī)劃鲤孵,是抱著大家一起開(kāi)心開(kāi)心,感受一種不太常有的編碼體驗(yàn)的態(tài)度進(jìn)行的辰如。在沒(méi)有預(yù)設(shè)目標(biāo)的情況下普监,反倒看到了代碼道場(chǎng)活動(dòng)的其它方面,以及可能的引入TDD的路徑琉兜。
收獲一凯正,自己最關(guān)注的,未必是參與者感受最深的
就像前面提到的豌蟋,Coding Dojo活動(dòng)雖說(shuō)是一般化的編程操練廊散,但是一開(kāi)始就與學(xué)習(xí)推廣極限編程技能緊密相關(guān),我也一直把學(xué)習(xí)TDD作為最核心的目標(biāo)梧疲。然而允睹,一位參與者的反饋卻讓我頗有感觸:
頭一次在掐表限時(shí)的環(huán)境下寫代碼,感覺(jué)非常新鮮幌氮。
聽(tīng)到這個(gè)感受時(shí)缭受,我突然意識(shí)到,由于自己參與過(guò)多次道場(chǎng)操練该互,反倒已經(jīng)看不到第一次參與者會(huì)注意的事情了米者。
- 比如限時(shí),平時(shí)除了面試宇智,幾乎是不會(huì)遇到的蔓搞。限時(shí)卻又不要求完成就連面試也不會(huì)碰到。
- 比如結(jié)對(duì)随橘,平時(shí)也只會(huì)有不常規(guī)的查錯(cuò)攻堅(jiān)時(shí)才能體驗(yàn)败明。
- 比如代碼review,雖然大部分公司流程里都會(huì)要求太防,不過(guò)現(xiàn)實(shí)中往往被進(jìn)度壓力追的無(wú)暇顧及妻顶,匆匆點(diǎn)過(guò)。像道場(chǎng)活動(dòng)那樣爭(zhēng)先恐后的要求上臺(tái)被review更是少而又少了蜒车。
- 比如重構(gòu)讳嘱,也是大家都提倡的。但是很少有機(jī)會(huì)說(shuō)干就干酿愧,一群人注視著改善一段代碼沥潭。
- 又比如單元測(cè)試,后面詳細(xì)展開(kāi)嬉挡。
收獲二钝鸽,單元測(cè)試是很好的切入點(diǎn)
通常討論起來(lái)TDD汇恤,不論是支持還是反對(duì)的,往往并沒(méi)有把概念理的很清楚拔恰。有時(shí)候他在說(shuō)因谎,我們做TDD,往往實(shí)際說(shuō)的是我們寫自動(dòng)化測(cè)試颜懊。
就我的觀察财岔,對(duì)于測(cè)試的接受程度,可以分為幾級(jí)河爹。
- 一切測(cè)試都是無(wú)用的匠璧,只有我的智慧和理性才是程序正確性的唯一保證。
這樣的大神從來(lái)沒(méi)見(jiàn)過(guò)咸这。 - 端到端測(cè)試有用夷恍,單元測(cè)試無(wú)用。
往往潛臺(tái)詞是這種測(cè)試需要大量的精力媳维。應(yīng)該由專門的測(cè)試人員負(fù)責(zé) - 單元測(cè)試是”正確“的事裁厅,但是對(duì)自己無(wú)用。
后半句一般不會(huì)實(shí)際說(shuō)出來(lái)侨艾,從實(shí)際中可以表現(xiàn)出來(lái)。比如說(shuō)起來(lái)應(yīng)該寫單元測(cè)試卻從來(lái)不寫拓挥。為了應(yīng)付覆蓋率指標(biāo)寫等等…… - 單元測(cè)試可以讓我開(kāi)發(fā)的更有效率唠梨。
達(dá)到這一步的程序員會(huì)很樂(lè)于自己去寫單元測(cè)試。就算還沒(méi)有掌握TDD侥啤,也只有一步之遙了当叭。
從活動(dòng)中觀察到的,大部分人都處于第三級(jí)的情況盖灸,也就是說(shuō)至少理論上認(rèn)為單元測(cè)試是有必要的蚁鳖,但是另一方面,很少有人實(shí)際在寫赁炎。
這幾次活動(dòng)沒(méi)有特意強(qiáng)調(diào)TDD或者寫代碼的方式醉箕,只是倡導(dǎo)性的希望至少寫一個(gè)測(cè)試。實(shí)際情況是這樣的:
- 很多組都可以在限時(shí)內(nèi)基本完成徙垫。整體速度高于強(qiáng)調(diào)按照TDD流程的操練活動(dòng)讥裤。
- 有部分組會(huì)寫測(cè)試。而不寫的組往往是限于單純的技術(shù)問(wèn)題姻报。比如不知道怎么引入測(cè)試框架己英,或者因?yàn)閺膩?lái)沒(méi)寫過(guò),也不想在有限的時(shí)間里再去研究測(cè)試寫法吴旋。
- 有些組沒(méi)寫測(cè)試损肛,但是采用了其它方法對(duì)代碼做了驗(yàn)證厢破。比如main方法驗(yàn)證,打印結(jié)果值治拿,做個(gè)簡(jiǎn)單UI進(jìn)行手工驗(yàn)證等摩泪。
- 在每輪代碼review時(shí),很自然的會(huì)反映出測(cè)試的作用忍啤。比如加勤,
- 你怎么知道自己完全實(shí)現(xiàn)了題目要求?
- 如果是xxx的情況輸出會(huì)是什么同波?
- 咦鳄梅?我明明調(diào)試的時(shí)候測(cè)過(guò)這種情況呀……
- code retreat活動(dòng)中,同一道題目會(huì)反復(fù)寫幾輪未檩。按照規(guī)則每輪都要?jiǎng)h除代碼從頭開(kāi)始戴尸。自然而然的就會(huì)有小組提出能否保留測(cè)試只刪除實(shí)現(xiàn)代碼。也就是說(shuō)只要開(kāi)始寫單元測(cè)試很快就會(huì)認(rèn)識(shí)到它的價(jià)值冤狡,并希望再次利用孙蒙。
- 在重復(fù)多輪的活動(dòng)中,會(huì)有越來(lái)越多的小組開(kāi)始寫測(cè)試悲雳,而且只要開(kāi)始寫挎峦,后面的輪次中都會(huì)保持或擴(kuò)充測(cè)試集。沒(méi)有人在嘗試后又放棄了這種方式合瓢。
可見(jiàn)代碼道場(chǎng)是個(gè)很好的機(jī)會(huì)讓更多人體驗(yàn)到了單元測(cè)試對(duì)開(kāi)發(fā)者的助益坦胶。也許要在日常工作中大規(guī)模使用,還需要克服種種困難比如良好的測(cè)試代碼風(fēng)格晴楔,依賴隔離等顿苇。但是只要開(kāi)發(fā)者自己覺(jué)得這件事是值得做的,相信這些都不是真正的問(wèn)題税弃。
收獲三纪岁,改變遠(yuǎn)比想象中簡(jiǎn)單
Code retreat 活動(dòng)中同一道題目會(huì)操練好幾輪,每輪有不同的挑戰(zhàn)则果。其中一輪是完全不許使用鼠標(biāo)幔翰。
大部分人的第一反應(yīng)是”這怎么可能“——當(dāng)然這不是真的極端困難的事,我也相信有人能做到西壮,但我不是那種花那么多精力記滿腦子快捷鍵鍵盤敲得飛起……
然而實(shí)際挑戰(zhàn)開(kāi)始后导匣,有趣的事情發(fā)生了。
開(kāi)始會(huì)有人完全無(wú)法工作了茸时,或者不得不申請(qǐng)幾次豁免贡定,暫且移動(dòng)一下鼠標(biāo)看看需要的快捷鍵。
十分鐘之后可都,沒(méi)有一組還在研究鼠標(biāo)鍵盤缓待,全都進(jìn)入到了代碼邏輯的處理中蚓耽。
這輪挑戰(zhàn)結(jié)束,已經(jīng)不再?gòu)?qiáng)制后旋炒,后面輪次大部分人會(huì)繼續(xù)使用剛剛熟悉的快捷鍵步悠。
也就是說(shuō)僅僅十分鐘,這件事就從“怎么可能”變成“自然而然”了瘫镇。出乎我自己的意料鼎兽。
仔細(xì)想來(lái),其實(shí)在組織代碼道場(chǎng)的活動(dòng)中铣除,我收獲過(guò)很多這樣的出乎意料谚咬。
- 擔(dān)心氣氛,因?yàn)槟愣纳姓常绦騿T很“悶”择卦。
然而實(shí)際中我從未碰到過(guò)冷場(chǎng)的情況,相反往往嗨得停不下來(lái)郎嫁。開(kāi)始我歸因?yàn)槲覀児镜臍夥杖谇⒈蹋髞?lái)歸于周末能來(lái)參加社區(qū)活動(dòng)人的主動(dòng)性。最后我發(fā)現(xiàn)泽铛,其實(shí)程序員本來(lái)就沒(méi)那么悶嘛尚辑,特別是有個(gè)合適的問(wèn)題的時(shí)候。 - 擔(dān)心結(jié)對(duì)編程的接受度盔腔。
活動(dòng)中大部分人都幾乎是瞬間接受這個(gè)設(shè)定的杠茬。無(wú)論實(shí)際中這種配置多么少見(jiàn)。 - 一些實(shí)際工作中遇到過(guò)的棘手問(wèn)題铲觉。
比如固執(zhí)己見(jiàn),過(guò)于尖銳的評(píng)判等等吓坚。事實(shí)上從未發(fā)生過(guò)……
最終我發(fā)現(xiàn)撵幽,在一個(gè)規(guī)則明確,目標(biāo)可控礁击,安全的環(huán)境中盐杂,大部分人都會(huì)更樂(lè)于作出嘗試,更容易作出改變哆窿。
這可能是代碼道場(chǎng)活動(dòng)在具體的編程技能外链烈,帶來(lái)的更大的收獲吧。