透視迭代開發

引子:我們爲什麼需要迭代開發?

我們都知道,人對於世界的認識是一項主觀活動,它受到各種因素的影響,使得我們不能夠一下子對所要認知的事物有一個清晰的瞭解。具體到軟件開發中來,我們會發現,你很難在開發之前弄清楚客戶所有的需求。一方面,客戶對自己想要什麼可能並沒有一個明確的想法,這就好比在買衣服的時候,我們在專賣店裏看到一個衣服,會覺得自己穿起來很帥,但是你仍然需要把它真實的穿在身上才能看到實際效果,而在你看到這件衣服之前,你能夠僅僅憑着想象在腦海裏刻畫出這件衣服的樣子麼?

 

其次,軟件工業中我們講究的是投入和產出比,軟件業的成本主要是人力資源的成本。這也是軟件項目對時間特別敏感的原因。時間比計劃延長一個月,對於一個數十人的團隊來說就意味着幾十萬的成本增加。但是又有誰能夠保證自己所做的軟件是完美無缺的呢?於是很多時候我們必須對已經開發的部分進行修正,而修正就需要時間。 傳統的開發方式下,很多軟件項目都是在匆忙交付後發現用戶不滿意,於是繼續修正,再次引發用戶的不滿意,再次修正,在這樣反覆地拖延中,客戶和軟件開發商都筋疲力盡。

 

我們需要迭代開發,是因爲我們深知對事物的認知就是一個探索的過程,軟件開發也是一樣。在溫博格《探索需求---設計前的質量》一書中提到:

 

美國第34任總統艾森豪威爾上將曾經說過,"計劃本身什麼都不是,而編制計劃的過程就是一切"。我們認同這樣的說法,並把它推廣到需求過程:
      產品什麼都不是,而開發的過程就是一切。
或用另一種方式表達:
      發現什麼都不是,而發現過程(探索過程)就是一切。

 

軟件項目本身的意義就在於和用戶一起探索他們真正需要的東西並且幫助他們實現。而這種探索,如同在第一段中我們闡述的那樣,需要不斷的反覆,如果我們沒有做好迭代和反覆的準備,而是希望一次性的把所有工作都做完並且還做得非常好,結果可能恰恰相反。

 

我們需要迭代開發,是因爲我們追求軟件質量的最大化。沒有人可以製造出完美無缺的東西,但是我們可以通過不斷的檢查和反饋,使得那些不適合的東西在早期被暴露出來,迭代給予了我們這樣一種檢查合反饋的機制,讓我們不必在事情結束的時候才驚奇的發現我們所一直努力在做的東西其實是一堆廢物。

實踐:正確實施迭代開發

事實上在業界,迭代開發的觀念早已經深入人心,然而有多少團隊在正確地實施着迭代方法呢?有多少團隊通過迭代得到了他們想要的東西呢?很多人簡單的把迭代理解爲開發的分階段進行。我們常常看到有項目經理們這樣說:我們打算通過4次迭代完成軟件的開發,第一次迭代,完成需求分析和軟件設計,第二次迭代,完成多少多少模塊的開發,第三次,完成其他多少模塊的開發,第四次,配置,部署,上線,測試,修正軟件bug。雖然我們言必稱“迭代”,但是這樣的迭代和過去傳統的瀑布型開發有多少區別?我們又能夠從這樣的僞迭代中得到什麼好處呢?

 

在本文以下部分將對迭代開發實踐中幾個關鍵方面進行闡述,這幾個方面我們概括爲以下關鍵詞:變化,週期,目標,反饋,合作

變化

迭代思想帶給我們最重要的一個啓示,就是要適應變化,要積極、主動地擁抱變化而不是拒絕變化

在過去的開發中,我們常常會拒絕變化,以需求分析工作爲例,有些項目組在需求分析完成後會要求用戶簽字,等到交付時,如果客戶有什麼意見,他們就會拿出那份客戶已經簽字畫押的文件來理直氣壯地說:這是你們簽字過的東西,我們做的難道不是和這裏所說的一樣麼?

是的,開發出來的可能是和需求定義文件的內容一樣的,但問題是:這份需求定義文件上描述的內容是不是真正能夠幫客戶實現自己的價值呢?難道我們進行軟件開發的目的就是讓客戶在一份他們根本不清楚有什麼意義的文件上簽字,然後用這個來反駁用戶的真正需求麼?我們在軟件立項之前總是會告訴用戶,這個即將開發的軟件會幫助他們如何如何。我們有什麼理由爲我們做不到這一點而理直氣壯地責備客戶呢?客戶親筆簽名的需求文檔難道不是我們整理出來並且講解給他們聽的麼?

如果一個軟件項目的目標是幫助客戶實現某一方面的增值,但是這種增值的目的並沒有達到,我們就可以認爲這個軟件項目是失敗的。即使軟件廠商通過這個項目達到了盈利的目的,滿腹牢騷的客戶也會把自己的意見傳播出去。而如果軟件廠商認爲這種事情是天經地義的話,那麼它在以後的軟件項目中也很難幫助自己的客戶實現他們想要的價值。

我們必須讓自己具有適應變化的能力。因爲這種變化是客戶需要的,因爲這種變化能夠讓軟件更能體現出自己的價值。我並不是說應該無條件地接受這種變化,但是我們可以在事前就這些問題和客戶進行充分的討論和溝通,讓他們明白,世界總是變化的,需求本身可能會變化,而這種變化需要人力和物力的支持。讓客戶也能夠適應自身的變化,這是非常重要的。

軟件開發中的每個人都應該對變化有着充分的準備。從事軟件業的人大都充滿了自信,系統分析師會認爲自己可以把所有的需求搞清楚,設計和開發人員會覺得他們做出來的東西完美地實現了需求。所以,如果我們對一個開發人員說:某某,你過去做的這個模塊不能用了,我們現在需要重新做起,通常我們會得到積極或者消極地抵制。

應該讓人們認識到:變化並不是對過去工作的否定,而是着眼於未來,使工作更加完善的必要手段。無論是需求,設計還是程序代碼,你不可能一次性就把它們做到完美,而只能通過不斷的修正,讓它趨近於完美。這個過程就是所謂的“重構”。

有些團隊爲了保持開發的穩定性,會 “凍結需求”。所謂的凍結,也就是說在一段時間內要客戶方代表承諾不對已經開發中的需求進行變動。如果你打算做這件事情,首先必須意識到,需求本身就是需求,它是不會因爲一個承諾就真正地“凍結”了。如果目前的需求定義並不能反映用戶真正的願景,在凍結的週期過去以後我們仍然需要對已經做完的工作進行修改。當然,如果需求變化太頻繁,在某些時候有必要對需求進行凍結以便讓開發更加平穩,同時也給軟件開發者和客戶一個反思的時間。但如果是需求分析工作方法有誤,那就有必要作一些檢討了。

要適應變化,我們需要讓客戶和開發團隊有心理上的準備,從而能夠以認真的態度來對待它。還需要有正確的方法來應對變化,比如對變化的成本估算,效果的跟蹤,如何快速有效的對各種變化進行反映等,這是我們必須注意的問題。

週期

很多人簡單的把迭代理解爲開發的分階段進行。有些項目經理會這樣說:我們打算通過4次迭代完成軟件的開發,第一次迭代,完成需求分析和軟件設計,第二次迭代,完成多少多少模塊的開發,第三次,完成其他多少模塊的開發,第四次,配置,部署,上線,測試,修正軟件bug。在這裏,雖然他們言必稱“迭代”,但是這樣的迭代和過去傳統的瀑布型開發有多少區別?

迭代開發是要分週期分階段地進行,但是不能認爲簡單地把開發週期劃分爲幾個不同的階段就是迭代。

很多人對於迭代週期有一些誤解,比如:

n         認爲迭代只適用於開發階段,而需求分析和設計工作則不在此範圍內。

n         認爲迭代週期可以拉得很長,比如兩個月,三個月,甚至一個季度,半年。

n         將需求分析,設計,開發,測試,部署,用戶反饋,修改當作完整的迭代週期,並要求在前一階段工作完全(或者大部分)完成以後再進行下一步工作(迭代)。

 

在一個迭代週期內,我們可以做什麼事情呢?可以說:所有的事情。如果你認爲迭代需要在需求分析完成之後才能開始,或者系統集成必須在所有迭代完成之後纔可以進行,你會獲得一個真正的瀑布流程開發。

一個迭代週期意味着對一些特定功能(用例)的探索。“探索”一詞可能隨情況不同而有不同的含義。對於抽象級別較高,模糊程度比較高的用例,我們需要通過和用戶的討論將它逐漸分解爲更加清楚和清晰的用例。對於目前我們認爲已經得到了詳細定義的需求,需要選取合適的部分進行設計和實現,通過這些部分的實現,對需求定義和技術可行性進行反饋。對那些在上次迭代中已經開發完的模塊,應該儘可能快速地讓用戶提出他們的意見,以便了解是否真正解決了用戶面臨的問題,以及還有沒有可以改進的方面,再根據這些意見安排下一階段的工作。

我們是否可以在開發進行之前把需求或者設計全部弄清楚呢?我認爲很難。因爲通常來講,用戶對於自己的需求只有一個模糊的概念。讓我們假設一個飲食業的例子,有一天餐廳經理把你叫入辦公室說:馬上設計一個新的菜譜,這個菜譜是爲某某特定人羣定製的,你要讓這些人感覺色香味俱全。不過在你把配料和烹調方法都設計出來之前,我們不打算讓大廚來具體做這道菜,我們不允許失敗,所以你的設計一定要一次成功,你可以用調查問卷,用戶面談等方法獲取最終用戶的需求,但是記住:你不能去做這道菜。

這樣的事情你可能會覺得很滑稽,但是在軟件業,類似的事情人們卻認爲是天經地義的。

迭代允許我們將開發本身也作爲需求探索的一部分,通過用戶對已經實現功能的反饋我們和用戶都會逐漸明白什麼樣的軟件是我們最終想要開發的。所以,不要等到所有(或者大部分)的分析完了纔開始開發,而是儘早對已經捕獲到的需求進行細化,儘早開發,以獲得反饋。

在安排迭代計劃時,應該指明,這次迭代的目標是什麼,在結束時應達到的里程碑是什麼。如果有任務提前達到了這個里程碑,我們可以提前結束迭代,或者順便在剩下的時間內安排其他的任務,但是要注意這種安排的合理性,不要因爲這個而使得迭代週期被延長。

在一次迭代到達所設定的結束日期時,就必須審視各項任務是否達到了里程碑的要求,如果有任務沒有達到,原因是什麼,我們是否需要對需求和技術方案做出調整。對於沒有達到里程碑要求的任務,我們可以採取的辦法有兩種:

n         將剩餘的工作列入下一次迭代計劃中去,

n         將本次迭代的結束時間向後延遲,等待任務的完成

 

前一種辦法適合於有很大工作量沒有完成的情況,這可能也同時說明計劃的制定有問題,在制定下次迭代計劃時應該考慮對任務完成時間進行調整。後一種辦法適合剩餘工作量不是很大的情況。

通常來說,一次迭代完成以後應該有一個產品的新版本可用。這也就意味着:將集成和發佈分散到每次迭代中去。藉助於一些自動化工具(比如ant),我們甚至可以做到每日構建。

一個迭代週期應該有多長呢?這並沒有一個統一的說法,而是應該視目標和可用的資源而定。但是,迭代週期不宜過長,也不宜過短。迭代週期過長的話,會延緩反饋的時間,可能將許多問題隱藏或是堆積了起來。迭代週期過短,會讓人身心疲勞,事情難有大的成效。一般來說,迭代週期應該在2-6周之間。如果安排的迭代週期超過了兩個月,你可能就必須審視一下迭代計劃的合理性了。

不要認爲下一次迭代應該和上次迭代的時間差不多,刻板地把所有迭代規定一個統一的時間是一個很壞的做法。但是你可以把以前迭代週期中的工作效率作爲估算下次迭代時間的一個依據。

目標

一次迭代必須有明確的目標:我們希望通過這次迭代達到什麼目的。在制定目標時,應該同時考慮另外一個問題:如何檢查該目標是否已經達成。這就是所謂的“里程碑”。

迭代計劃必須有明確而可行的目標。明確的意思是它應該是可度量的,不能太模糊,因爲你很難檢查一個模糊的目標是否達成。比如,我們可以說,這次迭代的目標是對xxx方面的需求作進一步細化和評審,完成xxx模塊的開發以加入到軟件的下一版本中去。這樣的目標是明確而且可行的。反過來,如果我們這樣說:我們要通過和用戶的討論明確絕大部分願景,同時要有一個初步的開發。“絕大部分”和“初步”這樣的詞讓人感到困惑:多少是絕大部分呢,在總量尚未明確的前提下,怎麼能夠知道完成的確是“絕大部分”而不是“一小部分”?“初步的開發”似乎告訴我們這次開發量比較小,但是具體開發哪個部分,或者開發到什麼程度,並沒有指出一個明確的概念。

由此產生了一個困惑,軟件項目是一個不斷探索的過程,我們怎麼能夠明確地對未來的事情作安排呢?譬如在項目初始調查用戶願景時,爲了實現“明確”的目標,是否這樣定義任務:完成20%的用戶願景調查?

很顯然,用戶願景總量到底有多少我們並不知道,所以在這次迭代完成以後如果我們問:是否真的完成了20%而不是15%?很難得到答案。

爲了避免出現這種情況,你必須換個角度來看問題,比如我們可以說:對xxx部門和yyy部門的用戶做願景調查。在迭代完成後,可以檢查是否這兩個部門所有用戶的訪談,調查都已經完成,是否這些部門每個人都認爲自己表達了全部的意思。

所以,如果你發現很難對制定的目標進行度量,那麼換一個角度來看事情吧,你可能就會找到一個合適的表達方式。如果你從所有的角度都看不到事情是可以度量的,那麼這可能意味着這件事情可能還沒有到應該去實施的地步,這時你應該把它從迭代計劃中去掉。對於這種情況,有人可能會說:那我們這次迭代可做的事情就很少了,如果真是這樣,那就進行一次小的迭代吧,可能把這次迭代的工作做完了以後就會有更多的工作可以安排了。

有些項目經理在日程表上,很詳細地寫着:第一次迭代,某月某日到某月某日,第二次迭代:某月某日到某月某日,第三次迭代。。。這樣的做法是不恰當的。因爲它假設了後面幾次迭代的任務量,但是實際上,在前面的工作完成之前,你很難對以後的工作得到一個明確地概念。而且在這樣的計劃上,可能並沒有用於測量迭代成果的里程碑,這樣的迭代最後很可能會演變成爲瀑布式的開發。所以,在一次迭代完成之前,不要對急着去計劃下次迭代,特別是不要試圖精確定義下次迭代的時間,因爲你連下次迭代要做什麼都還不清楚。

爲什麼目標的可度量性這麼重要呢?在團隊開發中,很多信息因爲人與人的交流不暢而無法得到正確地反饋,這讓我們沒有辦法實時地掌握項目的進展情況,退而求其次,我們必須階段性地瞭解這些信息。如果目標難以度量,迭代結束後我們很難明確到底有哪些工作沒有完成,也就無法看到事情的問題所在。

有些團隊中會要求每個成員每天對自己的工作進度以百分比的形式做彙報,他們以爲通過這樣的方式可以確實的掌握事情的進展,但實際上並不行,因爲軟件開發中存在很多不確定因素,有時候我們認爲事情已經完成了一大半,但是可能因爲技術或者其他的原因發現這一大半工作方向是錯的,這時候就要推倒重來,而且人們在彙報工作量的時候總是會有一些感情的因素在裏面,這就使那些看似精確的百分比打了個折扣。

所以,我們需要更加實際和細緻地劃分工作,對目標的完成情況進行度量。這也是迭代週期不能太長的一個原因:如果你把大量有前後關聯的工作劃分入一個迭代週期,在設定的結束到來時,突然發現只完成了一小部分,這時候雖然亡羊補牢仍然可以,但是中間浪費了大量的人力和物力。

反饋

一個男人在大街上走着,他並沒有發現褲子上的拉鍊已經鬆開了,雖然看到這個情況的人有很多,但他們有各種各樣的擔心,比如不想多管閒事,怕讓那個男人難堪,或者乾脆就是想看笑話。結果就是這個人繼續穿着一條敞開拉鍊的褲子在大街上行走。

這件事情至少帶給我們兩個啓示:1,得到反饋是重要的;2,要想得到正確的,有價值的反饋,你需要其他人的配合。

對於用戶需求來說,沒有用戶及時地反饋,我們就可能把那些不符合需求的開發繼續下去,由於軟件中各種功能和模塊的依賴性,這種不符合最後可能被放大到數倍。越遲得到反饋,問題可能就越大。

軟件開發中一個很重要的概念是“可行性”和“合理性”,無論我們做需求,設計還是開發,集成,測試,都會遇到這兩個問題。有些事情的可行性和合理性是我們可以通過事前的分析進行判斷的,但是有些問題就必須有一定的實踐作爲基礎。這也是一個反饋的問題。譬如說在某項目中技術架構師決定採取一個技術架構,但是經過一些階段的開發發現它有一些技術上問題不能實現用戶的關鍵需求,這時候就必須放棄它。

“反饋”意味着兩個意思,對一件事情的調查和根據調查做出決策。

在意識到反饋的重要性之後,你會要求所有的人都對迭代的成果做出反饋。可能存在的問題是,是不是所有的人都意識到了反饋的重要性並且認真地去做了呢?如果客戶認爲他們只需要對迭代出來的產品“看看而已”,那麼你就很難了解他們一些深層次的想法。再比如一次迭代中某些模塊開發的進度比較慢,開發人員可能會抱怨技術方案不能滿足要求,而實際的原因可能是設計不合理或者根本就是有人沒有認真工作。

中國國家隊前主教練米盧曾經說過“態度決定一切”,反饋作爲迭代開發中至關重要的一個方面,必須得到足夠的重視。

獲得反饋的方式和對於反饋信息的分析是另外一個重要的方面。一般來講,根據軟件開發角色的不同,我們非常關注的是兩類人的反饋:項目組之外的客戶和項目組之內的各種實施人員。

軟件項目一般都會要求客戶方安排專門的業務人員進行配合,在迭代開發中,這種配合不只是進行需求的整理和發掘,還包括對已經完成軟件版本的評測。在這個過程中應該有需求分析師的配合。

在每次迭代完成之後,軟件項目組應該有一些總結和分析活動。通過這些總結和分析,找到做得好和做得不好的方面。

在非迭代式的開發中,也有反饋的環節。比如通常在軟件交付階段會有一個試用期讓用戶提出意見。而軟件團隊在各種開發中都會有一些總結活動。迭代式開發的獨特之處在於儘量早地引入反饋機制;使得反饋機制更加制度化;並且,更加快速和靈活地分析這些反饋,把得到的結論應用到下一階段的開發中去。

對於一些機制引起的問題,比如組織結構不合理,角色分配不明確之類。最好有一個明確的問題記錄表。在每次迭代完成以後將這些問題記錄下來,同時在下次迭代中努力改善它。如果相同的問題連續出現在幾次迭代中,可能就說明項目管理出了問題。

合作

軟件團隊中的合作是人們一直都在提倡的。我們在這裏提到“合作”的意思並不只包含團隊內部的協作,還包括和客戶的合作。

迭代開發需要快速反應,這需要各種不通角色人員的配合。如果人們做事情總是拖拖拉拉,就會延緩軟件項目的進度。而且每個人對自己在迭代中應該做什麼事情必須很清楚,這需要事前的準備和角色的合理分配。

迭代需要用戶的配合,實際上最好能夠有客戶方真正的系統使用者參加到迭代過程中來,因爲他們是最有發言權的。很多項目中會讓項目經理或是系統分析師擔當客戶代表的角色,這樣做有很多弊病。有時出於各種原因客戶確實不能到現場配合的,我們也可以通過其他的途徑獲得客戶反饋。比如一個階段迭代完成以後,可以把相關操作用截屏加文字說明的方式發給客戶,讓他們對產品有一個直觀的印象。

爲了讓團隊能夠有效快速地配合,應該儘可能使用各種自動化工具。比如自動化測試管理工具,以及配置管理,集成以及發佈之類的工具。通過對這些工具的有效應用,使得各個成員能夠快速獲得信息。

迭代開發要擁抱變化,主動適應變化。要讓每個參與者都認識到這一點:不能夠固步自封,或者滿足於現有的成就,不去思考可改進的地方。從管理者的角度上,必須重視每一個反饋信息。

迭代開發追求對任務的度量。很多組織會把這種度量和員工的績效考評聯繫起來。這種做法可能是合適的,但是如果只是簡單衡量工作量或者工作完成速度和質量,有可能會比較片面。畢竟軟件開發是一個環環相扣的過程,表面上來看這個環節處理不好,實際上可能是準備工作做得不好,或者其他人的配合不好。

所以如果在迭代過程中出現了問題,一定要客觀地分析,特別是應該挖掘導致這些問題出現的深層次原因。譬如在一次迭代中測試人員發現了一些bug,但是兩次迭代過去了,這些bug仍然存在,這就說明對bug的處理不夠迅速(當然如果因爲某些原因這些事情被故意推遲了的情況不算)。這時就必須分析一下到底是什麼原因造成了信息的不通暢。而不能簡單地批評相關責任人。

總結

本文對迭代開發的五個關鍵(變化,週期,目標,反饋,合作)方面進行了討論。作爲一種方法論,迭代開發的好處在於它使軟件團隊變得更加靈活。在實施迭代開發的過程中,應注意不能流於形式化,切實做好每個環節的工作,這樣才能獲得滿意的結果。

 

Email:[email protected]

http://www.blogjava.net/jayliu

發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章