去年11月份的時(shí)候,我進(jìn)到了ThoughWorks實(shí)習(xí),開(kāi)始了我的TW生涯,從現(xiàn)在除去今年年初由于畢業(yè)論文斷斷續(xù)續(xù)的10天左右的請(qǐng)假,我已經(jīng)到ThoughtWorks1年了,現(xiàn)在我想來(lái)我聊聊我眼中的敏捷和我對(duì)敏捷的看法。它是比較主觀的看法。 首先,我必須得說(shuō)敏捷并不是完美無(wú)缺的,當(dāng)然也不是所有行業(yè),所有軟件項(xiàng)目都適合使用敏捷來(lái)開(kāi)發(fā)和管理的。很明顯的一個(gè)例子就是,你不能用敏捷來(lái)開(kāi)發(fā)NASA的航天飛機(jī)的軟件系統(tǒng)。從敏捷的理念我們會(huì)說(shuō),我們讓開(kāi)發(fā)航天飛機(jī)的起飛系統(tǒng),然后交付給NASA使用,之后再繼續(xù)交付降落等其他系統(tǒng),顯示這是行不通的,航天飛機(jī)不能在僅僅擁有起飛功能的時(shí)候就上天啊。敏捷里強(qiáng)調(diào)快速交付,快速響應(yīng),及時(shí)修復(fù)bug,因此我們會(huì)允許軟件存在潛在少量bug的時(shí)候讓其上線(xiàn),使用。這在航天飛行系統(tǒng)里面也是行不通的,因?yàn)樯婕暗饺说纳?,航天飛行系統(tǒng)應(yīng)該是不允許任何bug的。但我依然會(huì)說(shuō),敏捷是一種很好的理念和實(shí)踐,適合大部分IT企業(yè)使用,特別是互聯(lián)網(wǎng)企業(yè)和運(yùn)行互聯(lián)網(wǎng)產(chǎn)品的企業(yè)使用。
在現(xiàn)在互聯(lián)網(wǎng)時(shí)代,天下武功唯快不破。采用敏捷的實(shí)踐,初期開(kāi)發(fā)MVP(Minimal Valuable Product)產(chǎn)品,快速上線(xiàn),根據(jù)用戶(hù)的反饋不斷更新、改進(jìn)自己的產(chǎn)品,開(kāi)發(fā)新的功能,這樣周而復(fù)始,產(chǎn)品把用戶(hù)最喜歡,優(yōu)先級(jí)最高的功能永遠(yuǎn)都放在第一時(shí)間開(kāi)發(fā)、上線(xiàn)。根據(jù)用戶(hù)的反饋、統(tǒng)計(jì)數(shù)據(jù)的結(jié)果不斷調(diào)整產(chǎn)品的策略,這樣才能立于當(dāng)今互聯(lián)網(wǎng)。在我們身邊也許Github、 Flickr等都是很好的成功例子。 下面是我對(duì)于一些是非的意見(jiàn): - 結(jié)對(duì)編程能夠明顯提升代碼的質(zhì)量,讓團(tuán)隊(duì)成員對(duì)代碼的熟悉度大幅提升,但是我不贊成至始至終都是結(jié)對(duì)編程,應(yīng)該留時(shí)間進(jìn)行單獨(dú)編程,這樣雖然代碼質(zhì)量也許會(huì)有一些下降,但是如果伴以TDD對(duì)進(jìn)行輔佐,是不會(huì)下降太多,單獨(dú)編程有助于讓dev獨(dú)立思考,發(fā)揮創(chuàng)造力,很多時(shí)候會(huì)達(dá)到意想不到的結(jié)果。另外一點(diǎn)結(jié)果編程通常達(dá)不到兩個(gè)dev獨(dú)立編寫(xiě)代碼的效率,就像在《人月神話(huà)》中講到的那樣,1一個(gè)人如果需要開(kāi)發(fā)一個(gè)軟件需要100填,那么10個(gè)程序員10天肯定不能完成任務(wù)的,因?yàn)槠陂g還需要算上溝通的成本。
- 關(guān)于TDD,確有遇到過(guò)幾次絞盡腦汁也沒(méi)想明白怎么測(cè)試的case。但是我們?nèi)绻褂?隔離依賴(lài)(即mock依賴(lài),stub行為,如使用mockito中的:given().willReturn();或者when().thenReturn()等)的原則來(lái)編寫(xiě)測(cè)試,絕大多數(shù)情況都會(huì)變得豁然開(kāi)朗,就Java而言,遇到靜態(tài)方法,我們可以通過(guò)間接的調(diào)用去測(cè)試,對(duì)于無(wú)返回值的方法(void)我們可以采用驗(yàn)證行為的方法去測(cè)試(如使用mockito中的verify()函數(shù))。使用TDD的好處是不言而喻的,用測(cè)試代碼描述你的需求,表達(dá)你想要的結(jié)果,既保證了質(zhì)量也不用擔(dān)心會(huì)做出多余的功能。不過(guò)在開(kāi)發(fā)自己的小點(diǎn)子、小創(chuàng)意時(shí),我通常選擇Rails和Node.js進(jìn)行開(kāi)發(fā)因此TDD做得并不好,通產(chǎn)只是選擇性的對(duì)重要的部分進(jìn)行測(cè)試保證。
- 溝通勝于一切,跟項(xiàng)目中所有的人頻繁溝通,在實(shí)際項(xiàng)目中有一次是這樣的,對(duì)于story中一個(gè)對(duì)于生效時(shí)間信息的描述有些模糊,我沒(méi)有多想久自己認(rèn)為肯定的全局的生效時(shí)間,但是不曾想到,當(dāng)多個(gè)子產(chǎn)品出現(xiàn)時(shí),就不能依賴(lài)全局生效時(shí)間,因?yàn)槿稚r(shí)間是其中最大第一個(gè),而不一定是當(dāng)前所需準(zhǔn)確的生效時(shí)間,因此這個(gè)sotry在最后給BA 檢查的時(shí)候才發(fā)現(xiàn)這個(gè)bug,試想最初如果我沒(méi)有隨便假設(shè),而是馬上給BA發(fā)郵件溝通,問(wèn)清楚生效時(shí)間,也不會(huì)出現(xiàn)返工的情況。我個(gè)人認(rèn)為良好、高效的溝通甚至比寫(xiě)好代碼優(yōu)先級(jí)更高。
- 站會(huì)(stand up)既是一種對(duì)團(tuán)隊(duì)成員工作的可視化,了解彼此的進(jìn)度等情況,也是鍛煉表達(dá)能力、增強(qiáng)自信心的好機(jī)會(huì)。為何這樣講,因?yàn)樵谡緯?huì)上每個(gè)人需要用幾句話(huà)來(lái)概括自己前一天所做的一切,當(dāng)你講到你前一天做的一些進(jìn)步時(shí),團(tuán)隊(duì)為你真心叫好,難道不會(huì)讓你你增強(qiáng)自信心嗎?對(duì)于站會(huì)進(jìn)行的方式,有團(tuán)隊(duì)會(huì)選擇每個(gè)人依次講解前一天的工作內(nèi)容;也有人會(huì)選擇采用按照故事墻的方式來(lái)進(jìn)行,依次對(duì)每個(gè)列(analysis, ready for dev, in development, test, sign off等)進(jìn)行瀏覽等,當(dāng)講到自己的那個(gè)story時(shí),每個(gè)人需要更新自己前一天在這個(gè)story上的工作,這樣的好處是可以對(duì)每個(gè)story的情況進(jìn)行可視化。但是我個(gè)人更喜歡前者,這樣更加自由,但是目前在工作中基本嘗試的都是后者。
- 另外一點(diǎn)是盡早集成,這點(diǎn)感觸很深,大三的時(shí)候在一家公司實(shí)習(xí),當(dāng)時(shí)做一個(gè)原型系統(tǒng),兩三個(gè)人做一個(gè)模塊,到最后快要演示的時(shí)候,才把幾個(gè)模塊嘗試連到一起做集成測(cè)試。結(jié)果就是,所有人坐在一起進(jìn)行的進(jìn)行各種接口的連接、調(diào)用,bug修補(bǔ)。一旦連接成功就興奮到難以言表,仿佛很長(zhǎng)一段時(shí)間的工作都沒(méi)有這一下來(lái)得興奮。系統(tǒng)可以集成后,一直都提心吊膽,擔(dān)心其中某個(gè)東西會(huì)不會(huì)莫名掛掉,因?yàn)榧蓽y(cè)試都是使用人肉測(cè)試的啊。在展示的時(shí)候,各種緊張,安排專(zhuān)人時(shí)時(shí)刻刻注意到服務(wù)器。在敏捷中,我們要求及早進(jìn)行系統(tǒng)集成和和創(chuàng)建部署環(huán)境的腳本,每次CI的運(yùn)行都是一次集成測(cè)試,都是一次服務(wù)器的部署。因此不用擔(dān)心在realse的時(shí)候不能部署的情況。不過(guò)有一件事情是需要注意的,那就是數(shù)據(jù)庫(kù)的遷移,在開(kāi)發(fā)機(jī)器,測(cè)試服務(wù)器你還能每次部署的時(shí)候都干掉之前的數(shù)據(jù)庫(kù),重新創(chuàng)建,但是在部署到產(chǎn)品服務(wù)器的時(shí)候就需要小心了,在Java中我們可以用Flyway 達(dá)到類(lèi)似Rails中的 rake db migrate的效果。
另外,我認(rèn)為 switch pair(變還你結(jié)對(duì)同事)、 code review(團(tuán)隊(duì)成員坐到一起對(duì)團(tuán)隊(duì)前一天提交的代碼進(jìn)行瀏覽、解讀),這些都可以讓整個(gè)團(tuán)隊(duì)共享更多的上下文,還可以檢查出不到的代碼,學(xué)習(xí)好的代碼。 也許明年這個(gè)時(shí)候我對(duì)敏捷的看法又有不少新的見(jiàn)解,到時(shí)候再來(lái)分享。
|