不一樣的敏捷開發(fā)實(shí)踐
項(xiàng)目背景
2006年年初,一位客戶聯(lián)系我的公司,希望能夠?yàn)槠淦髽I(yè)創(chuàng)建一個(gè)企業(yè)網(wǎng)站項(xiàng)目。根據(jù)客戶的簡單描述,這個(gè)項(xiàng)目本質(zhì)上就是一個(gè)內(nèi)容管理系統(tǒng),并集成了論壇、FTP和電子郵件等功能,因此不算復(fù)雜。按照以往的經(jīng)驗(yàn)估計(jì),最多一個(gè)月就可以完成這個(gè)簡單的項(xiàng)目。
需求分析
大體而言,該項(xiàng)目的主要功能包括新聞和文章發(fā)布、產(chǎn)品發(fā)布以及后臺的用戶管理和權(quán)限設(shè)置,還有外圍的論壇、FTP和電子郵件系統(tǒng)。應(yīng)該是一個(gè)很簡單的Web應(yīng)用程序,通常情況下寫一個(gè)簡單的概要性文檔,就可以安排開發(fā)人員進(jìn)行實(shí)際編碼了。
但這個(gè)客戶是國有企業(yè),所以簡單的概要性文檔是顯然不可能通過領(lǐng)導(dǎo)審核的。為此,我和客戶一起,將網(wǎng)站所有的功能整理成了列表,并標(biāo)記出各個(gè)功能之間的關(guān)聯(lián)關(guān)系。功能和內(nèi)在邏輯關(guān)系整理完畢后,客戶還和設(shè)計(jì)師一起將所有網(wǎng)頁的布局也畫成了圖表。最終,需求文檔多達(dá)50頁。
在整理需求文檔的過程中,我發(fā)現(xiàn)項(xiàng)目并不像客戶最開始描述的那樣簡單。因?yàn)榭蛻羲诘钠髽I(yè)有一百多個(gè)部門、車間,所以客戶要求按照部門和車間對網(wǎng)站的用戶進(jìn)行管理。同時(shí),權(quán)限管理是層層授權(quán)的。簡單來說就是上級部門可以,也只能給直接下級部門授權(quán),而不能越級授權(quán)。獲得授權(quán)的用戶可以創(chuàng)建一個(gè)產(chǎn)品子類別。然后給子類別指定一個(gè)下級部門的管理員,然后再由該下級部門的管理員來創(chuàng)建更深層次的子類別或管理產(chǎn)品信息。
從表面上看,這種設(shè)計(jì)沒什么問題。但在實(shí)際操作中,這種設(shè)計(jì)要求對每一個(gè)部門的相關(guān)員工都進(jìn)行培訓(xùn),讓其掌握系統(tǒng)的使用,增大了項(xiàng)目的應(yīng)用成本。同時(shí),由于繁瑣的授權(quán)模式,最終負(fù)責(zé)產(chǎn)品管理的人員反倒沒有充分的權(quán)力使用系統(tǒng)。
所以我對這些不合理的地方提出了自己的看法,希望采取更靈活更實(shí)用的設(shè)計(jì)方案。不幸的是,我沒能說服客戶接受我的意見。畢竟這是個(gè)金額較大的項(xiàng)目,客戶方負(fù)責(zé)人堅(jiān)持己見,我也無可奈何。
雖然按照需求文檔,我把項(xiàng)目開發(fā)時(shí)間定為兩個(gè)月,但事實(shí)證明兩個(gè)月的時(shí)限過于樂觀。
原型系統(tǒng)開發(fā)和初步評審
文檔準(zhǔn)備完畢后,我安排了開發(fā)人員和設(shè)計(jì)師進(jìn)行此項(xiàng)目。而開發(fā)人員不到20天,就拿出了一個(gè)原型系統(tǒng),雖然細(xì)節(jié)上還有不少需要完善的地方,但主要功能都已經(jīng)具備了。原型系統(tǒng)開發(fā)完畢后,我們和客戶一起進(jìn)行了初步評審。評審結(jié)果雙方都比較滿意,所以準(zhǔn)備在余下來的時(shí)間中完善細(xì)節(jié)。
但我發(fā)現(xiàn)這個(gè)原型系統(tǒng)中權(quán)限部分實(shí)用性非常差,因此再次提出了修改意見。不過客戶顯然對于我這種“懷疑”他的做法很不愉快,最后用一句“這是我們行業(yè)特點(diǎn)決定的”來結(jié)束了討論。雖然我早已知道決定項(xiàng)目成敗的,“人”才是關(guān)鍵因素,但迫于客戶的壓力,我再次選擇了妥協(xié)。
許多開發(fā)者認(rèn)為只要原型系統(tǒng)通過評審,整個(gè)項(xiàng)目就不會遇到大問題了。但實(shí)際情況有時(shí)候非常復(fù)雜。因?yàn)樵拖到y(tǒng)通常只是幾個(gè)人坐在一起簡單展示或者試用一下,和實(shí)際使用該系統(tǒng)的環(huán)境有著巨大區(qū)別。所以許多問題是根本不可能在原型展示階段暴露出來的。
做好后的系統(tǒng)卻徹底失敗
從需求文檔準(zhǔn)備好到實(shí)際開發(fā)工作進(jìn)行還不到一個(gè)半月,整個(gè)系統(tǒng)就非常完善了。期間由于客戶方負(fù)責(zé)人出差,客戶企業(yè)的其他聯(lián)系人要么沒有決策權(quán),要么說不知道此事(國企通?。?,所以我們只有在沒有獲得進(jìn)一步反饋意見的情況下繼續(xù)按照需求文檔進(jìn)行開發(fā)。不過完善后的系統(tǒng)倒是“很順利”的通過了客戶的檢查,開始部署到服務(wù)器上進(jìn)行試運(yùn)行。
但就像火山一樣,系統(tǒng)中存在的問題超過臨界點(diǎn)就會爆發(fā)。短短一周以后,上門為客戶提供培訓(xùn)的技術(shù)支持人員就帶回來了一份詳細(xì)的修改意見文檔和反饋意見。而我僅僅看了這些文檔幾分鐘,就明白這個(gè)項(xiàng)目將要進(jìn)行重大修改,否則不可能投入實(shí)際應(yīng)用。
修改意見文檔的內(nèi)容主要集中在權(quán)限系統(tǒng)上,具體而言就是權(quán)限系統(tǒng)的設(shè)計(jì)太復(fù)雜、太死板。首先,層層授權(quán)太過繁瑣,有時(shí)候改變產(chǎn)品類別的名字也要找到上級管理員才行。其次,由于系統(tǒng)限定不能給一個(gè)管理人員分配多級產(chǎn)品分類的權(quán)限,所以必須每個(gè)產(chǎn)品分類層次都要設(shè)置不同的管理帳號。
客戶企業(yè)有10多個(gè)大類,100多個(gè)小類,上千種型號的產(chǎn)品。但實(shí)際上根本沒有那么多人愿意負(fù)責(zé)管理工作,最后就成了一個(gè)人用幾個(gè)帳號,當(dāng)初設(shè)想的嚴(yán)格權(quán)限管理形同虛設(shè)。而且由于使用太麻煩,實(shí)際的管理工作逐漸向少部分人集中,導(dǎo)致這些人怨聲載道,開始對系統(tǒng)提出各種各樣的負(fù)面看法。
在這種情況下,我公司和客戶企業(yè)領(lǐng)導(dǎo)進(jìn)行了多次會議,初步?jīng)Q定兩條腿走路。一方面用最短的時(shí)間修改現(xiàn)有系統(tǒng),保證客戶企業(yè)新產(chǎn)品發(fā)布時(shí),網(wǎng)站能夠正式推出。另一方面重新做一套新系統(tǒng)來替換現(xiàn)有系統(tǒng)。
重新開始,該如何抉擇?
對于軟件公司來說,一個(gè)項(xiàng)目如果重做,損失和影響是非常大的。因?yàn)椴坏渌拈_發(fā)計(jì)劃要被打亂,而且公司投入的成本也要成倍增加。這個(gè)時(shí)候,如何降低損失就是最重要的事情了。好在和和客戶經(jīng)過進(jìn)一步協(xié)商后,客戶承擔(dān)了一半的損失。而完全重做也改為只重做權(quán)限系統(tǒng)部分。
根據(jù)這個(gè)目標(biāo),我首先安排開發(fā)人員對系統(tǒng)進(jìn)行修改。砍掉了權(quán)限系統(tǒng)(實(shí)際上就是這一塊導(dǎo)致了整個(gè)系統(tǒng)的重做),并按照其他項(xiàng)目的成功經(jīng)驗(yàn),對多處功能進(jìn)行了修改。修改完成后的系統(tǒng)雖然缺乏權(quán)限管理,但其他功能經(jīng)過客戶企業(yè)員工使用都反映良好。而且這樣簡化后的系統(tǒng)大部分功能都可以直接搬到重新開發(fā)的新系統(tǒng)中,最大程度的降低了成本。
同時(shí),在我的強(qiáng)烈要求下,客戶企業(yè)決定安排專人負(fù)責(zé)此項(xiàng)目。這樣我才能保證新系統(tǒng)的開發(fā)不至于重蹈覆轍。#p#
引入敏捷開發(fā)
其實(shí)我公司不是第一次嘗試敏捷開發(fā),只是這個(gè)項(xiàng)目由于前期做了“細(xì)致”的文檔,所以沒有按照慣用的快速迭代模式進(jìn)行開發(fā)。但新系統(tǒng)在排除了“人”的障礙后,采用敏捷開發(fā)的條件已經(jīng)很充分了。
User Story
我首先和客戶方派來的代表一起模擬了權(quán)限系統(tǒng)的運(yùn)作方式,最終得到了一個(gè)和最初設(shè)計(jì)功能近似,但具備充分實(shí)用性的權(quán)限系統(tǒng)設(shè)計(jì)方案。
模擬過程類似角色扮演游戲。我先在許多張卡片上寫好各個(gè)部門及員工的名字、職位信息。然后我和客戶代表一起,手持不同的卡片扮演不同的角色。然后將不同角色之間的交互過程記錄下來。這個(gè)過程就是敏捷開發(fā)中倡導(dǎo)的“User Story”,雖然簡單,但是非常有效。不但能夠真正理清各個(gè)角色之間的關(guān)系,還能找出實(shí)際運(yùn)用時(shí)的不足之處。
在我和客戶代表的模擬過程中,開發(fā)人員則迅速創(chuàng)建一個(gè)符合我們演示過程的權(quán)限系統(tǒng)來驗(yàn)證權(quán)限系統(tǒng)的可行性。當(dāng)然,如此高要求的快速開發(fā)還需要借助公司從以往項(xiàng)目中積累的大量可復(fù)用代碼以及高水平的開發(fā)人員。
快速決策和充分溝通
由于在客戶企業(yè),一個(gè)很簡單的決策可能也要層層批復(fù)。所以經(jīng)過我公司的艱苦努力,客戶企業(yè)最終決定由一位領(lǐng)導(dǎo)來專門負(fù)責(zé)該項(xiàng)目的決策。所以大部分決策可以在較短的時(shí)間內(nèi)獲得反饋意見。
而客戶代表在整個(gè)新系統(tǒng)開發(fā)期間,幾乎一半時(shí)間都在我公司上班。這也保證了我公司和客戶之間的充分溝通,并且當(dāng)面溝通也比通過電話更容易說服客戶接受我的意見。
實(shí)際上,不管采用何種開發(fā)模式,充分的溝通都是保障項(xiàng)目成功的關(guān)鍵因素之一。溝通越充分、雙方協(xié)作程度越高,項(xiàng)目就會進(jìn)行得越順利,成功的幾率也更大。而在敏捷開發(fā)中,由于是通過小步前進(jìn)的快速迭代來逐步逼近項(xiàng)目最終目標(biāo),所以溝通就更為重要。否則一次迭代完成后,卻得不到及時(shí)和正確的反饋,那么項(xiàng)目也無法進(jìn)行下去。
有限的單元測試
持續(xù)集成雖然非常有用,但是對于這個(gè)項(xiàng)目卻不太適合。不過為了保證子系統(tǒng)的修改不至于影響到全局系統(tǒng),我仍然編寫了一些重要的單元測試。
準(zhǔn)確來說,這幾十個(gè)單元測試都不太符合“單元測試”的標(biāo)準(zhǔn)。因?yàn)槊總€(gè)測試實(shí)際上都要用到子系統(tǒng)的許多接口。但在項(xiàng)目時(shí)間壓力下,這些測試既能很大程度上保證子系統(tǒng)的修改不至于對全局系統(tǒng)產(chǎn)生太大的破壞作用,又不用花太多時(shí)間去維護(hù)。所以是一個(gè)折衷的選擇。
不過這里我認(rèn)為這里做得很好的地方就是單元測試是由我來編寫的,并不是開發(fā)人員自己編寫的,所以更能夠反映我和客戶的意圖。同時(shí)測試重點(diǎn)也更偏重業(yè)務(wù)領(lǐng)域,而不是程序行為。
版本控制系統(tǒng)
雖然敏捷開發(fā)沒有對版本控制系統(tǒng)做要求,但使用版本控制系統(tǒng)可以很明顯的提高開發(fā)效率。例如我和客戶代表驗(yàn)證一個(gè)想法后,發(fā)現(xiàn)這個(gè)設(shè)想并不好,那么通過版本控制系統(tǒng),開發(fā)人員幾分鐘就可以退回到先前的代碼或者切換到其他階段的代碼。
而且版本控制系統(tǒng)在需求變動激烈的項(xiàng)目中,更是充當(dāng)了一種保險(xiǎn)機(jī)制。無意中用錯(cuò)誤版本的代碼覆蓋工作拷貝的事情可以得到徹底解決。
靈活運(yùn)用敏捷開發(fā)
實(shí)際上,我從來沒有采用過完整的敏捷開發(fā)。因?yàn)槲艺J(rèn)為既然敏捷開發(fā)本身強(qiáng)調(diào)的就是應(yīng)對變化,那么敏捷開發(fā)過程本身也應(yīng)該是可剪裁的。像結(jié)對編程、持續(xù)集成這些,對公司本身和開發(fā)人員的要求相對來說都更高。如果要一一達(dá)標(biāo),確實(shí)不太可能。所以有選擇性的實(shí)行敏捷開發(fā),是我最常用的方式。
例如對于User Story,除非是客戶充分配合,否則是難以實(shí)施的。這個(gè)時(shí)候應(yīng)該在前期將工作做細(xì)致,盡可能明確大部分需求。然后以最快的速度做出原型系統(tǒng)后,和客戶進(jìn)行溝通獲取反饋意見。
同時(shí),即便采用User Story,對于較復(fù)雜的系統(tǒng),也應(yīng)該深入客戶企業(yè),了解客戶企業(yè)員工的工作流程。因?yàn)橛袝r(shí)候客戶方負(fù)責(zé)項(xiàng)目的人士很可能會按照自己的想法渲染實(shí)際的工作流程或者環(huán)境,這對項(xiàng)目的中后期是非常不利的。
在國內(nèi),一個(gè)項(xiàng)目要做得順利,項(xiàng)目負(fù)責(zé)人還要懂得“做人”。和客戶方負(fù)責(zé)人、聯(lián)系人保持良好的關(guān)系是非常非常重要的,否則他們一句話可能就會讓項(xiàng)目的開發(fā)成本增加不少。這些東西的內(nèi)容遠(yuǎn)遠(yuǎn)超過了技術(shù)領(lǐng)域,但卻是我們不得不面對的問題。
遲來的成功
新系統(tǒng)花了一個(gè)月就開發(fā)完成了,因?yàn)槌藱?quán)限系統(tǒng)是完全重做的外,其他部分都大量利用了已有系統(tǒng)的結(jié)構(gòu)和代碼。雖然在模擬權(quán)限系統(tǒng)時(shí)花了不少時(shí)間,但這樣模擬的結(jié)果保證整個(gè)系統(tǒng)具有充分的可用性。
這個(gè)項(xiàng)目是我公司迄今為止用FleaPHP應(yīng)用程序開發(fā)框架開發(fā)的最復(fù)雜的應(yīng)用程序。不算FleaPHP自身在內(nèi),應(yīng)用程序的核心有100多個(gè)類,6700多行代碼。從與客戶意向性洽談到最后完成,足足花了六個(gè)月時(shí)間,期間開發(fā)實(shí)際上只進(jìn)行了三個(gè)月不到,而且還是做了兩次。其他時(shí)間全花在溝通、協(xié)調(diào)、開會上了(有時(shí)候不得不抱怨一下國有企業(yè)僵化的機(jī)制)。
如果我一開始能夠耐心說服客戶接受我的意見,那么整個(gè)項(xiàng)目的開發(fā)過程可能就會順利得多。或者說我能在項(xiàng)目初審發(fā)現(xiàn)問題后通過其他渠道爭取支持,那么也可以避免后來的二次開發(fā)。不得不說我在如何“做人”方面還有許多需要學(xué)習(xí)的東西。
【編輯推薦】