迭代是一種軟件開發(fā)的生命周期模型,在設(shè)計(jì)中應(yīng)用迭代設(shè)計(jì),我們可以得到很多的好處。
在軟件生命周期中,我們?nèi)绾螌?duì)待架構(gòu)設(shè)計(jì)的發(fā)展?
架構(gòu)設(shè)計(jì)往往發(fā)生在細(xì)節(jié)需求尚未完成的時(shí)候進(jìn)行的。因此,隨著項(xiàng)目的進(jìn)行,需求還可能細(xì)化,可能變更。原先的架構(gòu)肯定會(huì)有不足或錯(cuò)誤的地方。那么,我們應(yīng)該如何對(duì)待原先的設(shè)計(jì)呢?
我們?cè)诤?jiǎn)單設(shè)計(jì)模式中簡(jiǎn)單提到了"Planned Design"和"Evolutionary Design"的區(qū)別。XP社團(tuán)的人們推崇使用"Evolutionary Design"的方式,在外人看來(lái),似乎擁護(hù)者們從來(lái)不需要架構(gòu)的設(shè)計(jì),他們采用的方式是一開始就進(jìn)入代碼的編寫,然后用Refactoring來(lái)改進(jìn)代碼的質(zhì)量,解決未經(jīng)設(shè)計(jì)導(dǎo)致的代碼質(zhì)量低下的功能。
從一定程度上來(lái)說,這個(gè)觀點(diǎn)并沒有錯(cuò),它強(qiáng)調(diào)了代碼對(duì)軟件的重要性,并通過一些技巧(如Refactoring)來(lái)解決缺乏設(shè)計(jì)的問題。但我并不認(rèn)同"Evolutionary Design"的方式,在我看來(lái),一定程度上的"Planned Design"是必須的,至少在中國(guó)的軟件行業(yè)中,"Planned Design"還沒有成為主要的設(shè)計(jì)方向。借用一句明言,"凡事預(yù)則立,不預(yù)則廢",在軟件設(shè)計(jì)初期,投入精力進(jìn)行架構(gòu)的設(shè)計(jì)是很有必要的,這個(gè)架構(gòu)是你在后續(xù)的設(shè)計(jì)、編碼過程中依賴的基礎(chǔ)。但是,一開始我們提到的設(shè)計(jì)改進(jìn)的問題依然存在,我們?nèi)绾谓鉀Q它呢?
在簡(jiǎn)單設(shè)計(jì)模式中,我們提到了設(shè)計(jì)改進(jìn)的必要性,但是,如果沒有一種方法去控制設(shè)計(jì)的改進(jìn)的話,那么設(shè)計(jì)改進(jìn)本身就是一場(chǎng)噩夢(mèng)。因此,何時(shí)改進(jìn),怎么改進(jìn), 如何控制,這都是我們需要面對(duì)的問題。
解決方法
為了實(shí)現(xiàn)不斷的改進(jìn),我們將在開發(fā)流程中引入迭代的概念。迭代的概念在《需求的實(shí)踐》中已經(jīng)提到,這里我們假設(shè)讀者已經(jīng)有了基本的迭代的概念。
軟件編碼之前的工作大致可以分為這樣一個(gè)工作流程:
上圖中的流程隱含著一個(gè)信息的損失的過程。來(lái)自于用戶的需求經(jīng)過整理之后,開發(fā)人員就會(huì)從中去掉一些信息,同樣的事情發(fā)生在后面的過程中,信息丟失或變形的情況不斷的發(fā)生。這里發(fā)生了什么問題?應(yīng)該說,需求信息的失真是非常普遍的,我們?nèi)鄙俚氖且环N有效的辦法來(lái)抑止失真,換句話說,就是缺少反饋。
如果把眼睛蒙上,那我們肯定沒有辦法走出一條很長(zhǎng)的直線。我們走路的時(shí)候都是針對(duì)目標(biāo)不斷的調(diào)整自己的方向的。同樣的,漫長(zhǎng)的軟件開發(fā)過程如果沒有一種反饋機(jī)制來(lái)調(diào)整方向,那最后的軟件真是難以想象。
所以我們引入了迭代周期。
初始設(shè)計(jì)和迭代設(shè)計(jì)
在團(tuán)隊(duì)設(shè)計(jì)中,我們一直在強(qiáng)調(diào),設(shè)計(jì)組最開始得到的設(shè)計(jì)一定只是一個(gè)原始架構(gòu),然后把這個(gè)原始架構(gòu)傳播到每一位開發(fā)者的手中,從而在開發(fā)團(tuán)隊(duì)中形成共同的愿景。(愿景(Vision):源自于管理學(xué),表示未來(lái)的愿望和景象。這里借用來(lái)表示軟件在開發(fā)人員心中的樣子。在后面的文章中我們會(huì)有一個(gè)章節(jié)專門的討論架構(gòu)愿景。)
迭代(Iterate)設(shè)計(jì),或者我們稱之為增量(Incremental)設(shè)計(jì)的思想和XP提倡的Evolutionary Design有異曲同工之妙。我們可以從XP、Crystal、RUP、ClearRoom等方法學(xué)中對(duì)比、體會(huì)迭代設(shè)計(jì)的精妙之處:每一次的迭代都是在上一次迭代的基礎(chǔ)上進(jìn)行的,迭代將致力于重用、修改、增強(qiáng)目前的架構(gòu),以使架構(gòu)越來(lái)越強(qiáng)壯。在軟件生命周期的最后,我們除了得到軟件,還得到了一個(gè)非常穩(wěn)定的架構(gòu)。對(duì)于一個(gè)軟件組織來(lái)說,這個(gè)架構(gòu)很有可能就是下一個(gè)軟件的投入或參考。
我們可以把早期的原始架構(gòu)當(dāng)作第一次迭代前的早期投入,也可以把它做為第一次迭代的重點(diǎn),這些都是無(wú)所謂的。關(guān)鍵在于,原始架構(gòu)對(duì)于后續(xù)的架構(gòu)設(shè)計(jì)而言是非常重要的,我們討論過架構(gòu)是來(lái)源于需求的,但是原始架構(gòu)應(yīng)該來(lái)源于那些比較穩(wěn)定的需求。
TIP:現(xiàn)實(shí)中迭代設(shè)計(jì)退化為"Code and Fix"的設(shè)計(jì)的情況屢見不鮮("Code and Fix"參見簡(jiǎn)單設(shè)計(jì))。從表面上看,兩者的做法并沒有太大的差別,都是針對(duì)原有的設(shè)計(jì)進(jìn)行改進(jìn)。但是,二者效果的差別是明顯的:"Code and Fix"是混沌的,毫無(wú)方向感可言,每一次的改進(jìn)只是給原先就已搖搖欲墜的積木上再加一塊積木而已。而迭代設(shè)計(jì)的每一次改進(jìn)都朝著一個(gè)穩(wěn)定的目標(biāo)在前進(jìn),他給開發(fā)人員帶來(lái)信心,而不是打擊。在過程上,我們說迭代設(shè)計(jì)是在控制之下的。從實(shí)踐的經(jīng)驗(yàn)中,我們發(fā)現(xiàn),把原該在目前就該解決的問題退后是造成這一問題的主要原因之一。因此,請(qǐng)嚴(yán)格的對(duì)待每一次的迭代,確保計(jì)劃已經(jīng)完成、確保軟件的質(zhì)量、確保用戶的需求得到滿足,這樣才是正統(tǒng)的迭代之路。
單次的迭代
我們說,每一次的迭代其實(shí)是一個(gè)完整的小過程。也就是說,它同樣要經(jīng)歷文章中討論的這些過程模式。只不過,這些模式的工作量都不大,你甚至可以在很短的時(shí)間內(nèi)做完所有的事情。因此,我們好像又回到了文章的開頭,重新討論架構(gòu)設(shè)計(jì)的過程。
單次迭代最令我們興奮的就是我們總是可以得到一個(gè)在當(dāng)前迭代中相當(dāng)穩(wěn)定的結(jié)果,而不像普通的架構(gòu)設(shè)計(jì)那樣,我們深怕架構(gòu)會(huì)出現(xiàn)問題,但又不得不依賴這個(gè)架構(gòu)。從心理上來(lái)分析,我們是在持續(xù)的建設(shè)架構(gòu)中,不需要回避需求的變更,因?yàn)槲覀兿嘈牛谛枨笙鄬?duì)應(yīng)的迭代中,會(huì)繼續(xù)對(duì)架構(gòu)進(jìn)行改進(jìn)。大家不要認(rèn)為這種心理的改變是無(wú)關(guān)緊要的,我起初并沒有意識(shí)到這個(gè)問題,但是我很快發(fā)現(xiàn)新的架構(gòu)設(shè)計(jì)過程仍然籠罩在原先的懼怕改變的陰影之下的時(shí)候,迭代設(shè)計(jì)很容易就退化為"Code and Fix"的情形。開發(fā)人員難以接受新方法的主要原因還是在心理上。因此,我不得不花了很多的時(shí)間來(lái)和開發(fā)人員進(jìn)行溝通,這就是我現(xiàn)實(shí)的經(jīng)驗(yàn)。
迭代的交錯(cuò)
基于我們對(duì)運(yùn)籌學(xué)的一點(diǎn)經(jīng)驗(yàn),迭代設(shè)計(jì)之間肯定不是線性的關(guān)系。這樣說的一個(gè)原因架構(gòu)設(shè)計(jì)和后續(xù)的工作間還是時(shí)間差的。因此,我們不會(huì)傻到把時(shí)間浪費(fèi)在等待其它工作上。一般而言,當(dāng)下一次迭代的需求開始之后,詳細(xì)需求開始之前,我們就已經(jīng)可以開始下一次迭代的架構(gòu)設(shè)計(jì)了。
各次迭代之間的時(shí)間距離要視項(xiàng)目的具體情況而定。比如,人員比較緊張的項(xiàng)目中,主要的架構(gòu)設(shè)計(jì)人員可能也要擔(dān)任編碼人員的角色,下一次迭代的架構(gòu)設(shè)計(jì)就可能要等到編碼工作的高峰期過了之后。可是,多次的交錯(cuò)迭代就可能產(chǎn)生版本的問題。比如,本次的迭代的編碼中發(fā)現(xiàn)了架構(gòu)的一個(gè)問題,反饋給架構(gòu)設(shè)計(jì)組,但是架構(gòu)設(shè)計(jì)組已經(jīng)根據(jù)偽修改的本次迭代的架構(gòu)開始了下一次迭代的架構(gòu)設(shè)計(jì),這時(shí)候就會(huì)出現(xiàn)不同的設(shè)計(jì)之間的沖突問題。這種情況當(dāng)然可以通過加強(qiáng)對(duì)設(shè)計(jì)模型的管理和引入版本控制機(jī)制來(lái)解決,但肯定會(huì)隨之帶來(lái)管理成本上升的問題,而這是不符合敏捷的思想的。這時(shí)候,團(tuán)隊(duì)設(shè)計(jì)就體現(xiàn)了他的威力了,這也是我們?cè)趫F(tuán)隊(duì)設(shè)計(jì)中沒有提到的一個(gè)原因。團(tuán)隊(duì)設(shè)計(jì)通過完全的溝通,可以解決架構(gòu)設(shè)計(jì)中存在沖突的問題。
迭代頻率
XP提倡迭代周期越短越好(XP建議為一到兩周),這是個(gè)不錯(cuò)的提議。在這么短的一個(gè)迭代周期內(nèi),我們花在架構(gòu)設(shè)計(jì)上的時(shí)間可能就只有一兩個(gè)小時(shí)到半天的時(shí)間。這時(shí)候,會(huì)有一個(gè)很有意思的現(xiàn)象,你很難去區(qū)分架構(gòu)設(shè)計(jì)和設(shè)計(jì)的概念了。因?yàn)樵谶@么短的一個(gè)周期之內(nèi),完成的需求數(shù)量是很少的,可能就只有一兩個(gè)用例或用戶素材。因此,這幾項(xiàng)需求的設(shè)計(jì)是不是屬于架構(gòu)設(shè)計(jì)呢?如果是的話,由于開發(fā)過程是由多次的迭代組成的,那么開發(fā)過程中的設(shè)計(jì)不都屬于架構(gòu)設(shè)計(jì)了嗎?我們說,架構(gòu)是一個(gè)相對(duì)的概念,是針對(duì)范圍而言的,在傳統(tǒng)的瀑布模型中,我們可以很容易的區(qū)分出架構(gòu)設(shè)計(jì)和普通設(shè)計(jì),如果我們把一次迭代看作是一個(gè)單獨(dú)的生命周期,那么,普通的設(shè)計(jì)在這樣一個(gè)范圍之內(nèi)也就是架構(gòu)設(shè)計(jì),他們并沒有什么兩樣。但是,迭代周期中的架構(gòu)設(shè)計(jì)是要遵循一定的原則的,這我們?cè)谙旅孢€會(huì)提到。
我們希望迭代頻率越快越好,但是這還要根據(jù)現(xiàn)實(shí)的情況而定。比如數(shù)據(jù)倉(cāng)庫(kù)項(xiàng)目,在項(xiàng)目的初期階段,我們不得不花費(fèi)大量的時(shí)間來(lái)進(jìn)行數(shù)據(jù)建模的工作,這其實(shí)也是一項(xiàng)專門針對(duì)數(shù)據(jù)的架構(gòu)設(shè)計(jì),建立元數(shù)據(jù),制定維,整理數(shù)據(jù),這樣子的過程很難分為多次的迭代周期來(lái)實(shí)現(xiàn)。
如何確定軟件的迭代周期
可以說,如果一支開發(fā)團(tuán)隊(duì)沒有相關(guān)迭代的概念,那么這支團(tuán)隊(duì)要立刻實(shí)現(xiàn)時(shí)隔兩周迭代周期是非常困難的,,同時(shí)也是毫無(wú)意義的。就像我們?cè)谏厦嬗懻摰?,影響迭代周期的因素很多,以至于我們那無(wú)法對(duì)迭代周期進(jìn)行量化的定義。因此我們只能從定性的角度分析迭代周期的發(fā)展。
另一個(gè)了解迭代的方法是閱讀XP的相關(guān)資料,我認(rèn)為XP中關(guān)于迭代周期的使用是很不錯(cuò)的一種方法,只是他強(qiáng)調(diào)的如此短的迭代周期對(duì)于很多的軟件團(tuán)隊(duì)而言都是難以實(shí)現(xiàn)的。
迭代周期的引入一定是一個(gè)從粗糙到精確的過程。迭代的本質(zhì)其實(shí)是短周期的計(jì)劃,因此這也是迭代周期越短對(duì)我們?cè)接泻锰幍囊淮笤?,因?yàn)闀r(shí)間縮短了,計(jì)劃的可預(yù)測(cè)性就增強(qiáng)了。我們知道,計(jì)劃的制定是依賴于已往的經(jīng)驗(yàn),如果原先我們沒有制定計(jì)劃或細(xì)節(jié)計(jì)劃的經(jīng)驗(yàn),那么我們的計(jì)劃就一定是非常粗糙,最后的誤差也一定很大。但是這沒有關(guān)系,每一次的計(jì)劃都會(huì)對(duì)下一次的計(jì)劃產(chǎn)生正面的影響,等到經(jīng)驗(yàn)足夠的時(shí)候,計(jì)劃將會(huì)非常的精確,最后的誤差也會(huì)很小。
迭代周期的確定需要依賴于單位工作量。單位工作量指的是一定時(shí)間內(nèi)你可以量化的最小的績(jī)效。最簡(jiǎn)單的單位工作量是每位程序員一天的編碼行數(shù)??上э@示往往比較殘酷,團(tuán)隊(duì)中不但有程序員的角色,還有設(shè)計(jì)師、測(cè)試人員、文檔制作人員等角色的存在,單純的編碼行數(shù)是不能夠作為的統(tǒng)計(jì)依據(jù)的。同樣,只強(qiáng)調(diào)編碼行數(shù),也會(huì)導(dǎo)致其它的問題,例如代碼質(zhì)量。為了保證統(tǒng)計(jì)的合理性,比較好的做法是一個(gè)團(tuán)隊(duì)實(shí)現(xiàn)某個(gè)功能所花費(fèi)的天數(shù)作為單位工作量。這里討論的內(nèi)容實(shí)際是軟件測(cè)量技術(shù),如果有機(jī)會(huì)的話,再和大家探討這個(gè)問題。
在軟件生命周期中,我們?nèi)绾螌?duì)待架構(gòu)設(shè)計(jì)的發(fā)展?
架構(gòu)設(shè)計(jì)往往發(fā)生在細(xì)節(jié)需求尚未完成的時(shí)候進(jìn)行的。因此,隨著項(xiàng)目的進(jìn)行,需求還可能細(xì)化,可能變更。原先的架構(gòu)肯定會(huì)有不足或錯(cuò)誤的地方。那么,我們應(yīng)該如何對(duì)待原先的設(shè)計(jì)呢?
我們?cè)诤?jiǎn)單設(shè)計(jì)模式中簡(jiǎn)單提到了"Planned Design"和"Evolutionary Design"的區(qū)別。XP社團(tuán)的人們推崇使用"Evolutionary Design"的方式,在外人看來(lái),似乎擁護(hù)者們從來(lái)不需要架構(gòu)的設(shè)計(jì),他們采用的方式是一開始就進(jìn)入代碼的編寫,然后用Refactoring來(lái)改進(jìn)代碼的質(zhì)量,解決未經(jīng)設(shè)計(jì)導(dǎo)致的代碼質(zhì)量低下的功能。
從一定程度上來(lái)說,這個(gè)觀點(diǎn)并沒有錯(cuò),它強(qiáng)調(diào)了代碼對(duì)軟件的重要性,并通過一些技巧(如Refactoring)來(lái)解決缺乏設(shè)計(jì)的問題。但我并不認(rèn)同"Evolutionary Design"的方式,在我看來(lái),一定程度上的"Planned Design"是必須的,至少在中國(guó)的軟件行業(yè)中,"Planned Design"還沒有成為主要的設(shè)計(jì)方向。借用一句明言,"凡事預(yù)則立,不預(yù)則廢",在軟件設(shè)計(jì)初期,投入精力進(jìn)行架構(gòu)的設(shè)計(jì)是很有必要的,這個(gè)架構(gòu)是你在后續(xù)的設(shè)計(jì)、編碼過程中依賴的基礎(chǔ)。但是,一開始我們提到的設(shè)計(jì)改進(jìn)的問題依然存在,我們?nèi)绾谓鉀Q它呢?
在簡(jiǎn)單設(shè)計(jì)模式中,我們提到了設(shè)計(jì)改進(jìn)的必要性,但是,如果沒有一種方法去控制設(shè)計(jì)的改進(jìn)的話,那么設(shè)計(jì)改進(jìn)本身就是一場(chǎng)噩夢(mèng)。因此,何時(shí)改進(jìn),怎么改進(jìn), 如何控制,這都是我們需要面對(duì)的問題。
解決方法
為了實(shí)現(xiàn)不斷的改進(jìn),我們將在開發(fā)流程中引入迭代的概念。迭代的概念在《需求的實(shí)踐》中已經(jīng)提到,這里我們假設(shè)讀者已經(jīng)有了基本的迭代的概念。
軟件編碼之前的工作大致可以分為這樣一個(gè)工作流程:
上圖中的流程隱含著一個(gè)信息的損失的過程。來(lái)自于用戶的需求經(jīng)過整理之后,開發(fā)人員就會(huì)從中去掉一些信息,同樣的事情發(fā)生在后面的過程中,信息丟失或變形的情況不斷的發(fā)生。這里發(fā)生了什么問題?應(yīng)該說,需求信息的失真是非常普遍的,我們?nèi)鄙俚氖且环N有效的辦法來(lái)抑止失真,換句話說,就是缺少反饋。
如果把眼睛蒙上,那我們肯定沒有辦法走出一條很長(zhǎng)的直線。我們走路的時(shí)候都是針對(duì)目標(biāo)不斷的調(diào)整自己的方向的。同樣的,漫長(zhǎng)的軟件開發(fā)過程如果沒有一種反饋機(jī)制來(lái)調(diào)整方向,那最后的軟件真是難以想象。
所以我們引入了迭代周期。
初始設(shè)計(jì)和迭代設(shè)計(jì)
在團(tuán)隊(duì)設(shè)計(jì)中,我們一直在強(qiáng)調(diào),設(shè)計(jì)組最開始得到的設(shè)計(jì)一定只是一個(gè)原始架構(gòu),然后把這個(gè)原始架構(gòu)傳播到每一位開發(fā)者的手中,從而在開發(fā)團(tuán)隊(duì)中形成共同的愿景。(愿景(Vision):源自于管理學(xué),表示未來(lái)的愿望和景象。這里借用來(lái)表示軟件在開發(fā)人員心中的樣子。在后面的文章中我們會(huì)有一個(gè)章節(jié)專門的討論架構(gòu)愿景。)
迭代(Iterate)設(shè)計(jì),或者我們稱之為增量(Incremental)設(shè)計(jì)的思想和XP提倡的Evolutionary Design有異曲同工之妙。我們可以從XP、Crystal、RUP、ClearRoom等方法學(xué)中對(duì)比、體會(huì)迭代設(shè)計(jì)的精妙之處:每一次的迭代都是在上一次迭代的基礎(chǔ)上進(jìn)行的,迭代將致力于重用、修改、增強(qiáng)目前的架構(gòu),以使架構(gòu)越來(lái)越強(qiáng)壯。在軟件生命周期的最后,我們除了得到軟件,還得到了一個(gè)非常穩(wěn)定的架構(gòu)。對(duì)于一個(gè)軟件組織來(lái)說,這個(gè)架構(gòu)很有可能就是下一個(gè)軟件的投入或參考。
我們可以把早期的原始架構(gòu)當(dāng)作第一次迭代前的早期投入,也可以把它做為第一次迭代的重點(diǎn),這些都是無(wú)所謂的。關(guān)鍵在于,原始架構(gòu)對(duì)于后續(xù)的架構(gòu)設(shè)計(jì)而言是非常重要的,我們討論過架構(gòu)是來(lái)源于需求的,但是原始架構(gòu)應(yīng)該來(lái)源于那些比較穩(wěn)定的需求。
TIP:現(xiàn)實(shí)中迭代設(shè)計(jì)退化為"Code and Fix"的設(shè)計(jì)的情況屢見不鮮("Code and Fix"參見簡(jiǎn)單設(shè)計(jì))。從表面上看,兩者的做法并沒有太大的差別,都是針對(duì)原有的設(shè)計(jì)進(jìn)行改進(jìn)。但是,二者效果的差別是明顯的:"Code and Fix"是混沌的,毫無(wú)方向感可言,每一次的改進(jìn)只是給原先就已搖搖欲墜的積木上再加一塊積木而已。而迭代設(shè)計(jì)的每一次改進(jìn)都朝著一個(gè)穩(wěn)定的目標(biāo)在前進(jìn),他給開發(fā)人員帶來(lái)信心,而不是打擊。在過程上,我們說迭代設(shè)計(jì)是在控制之下的。從實(shí)踐的經(jīng)驗(yàn)中,我們發(fā)現(xiàn),把原該在目前就該解決的問題退后是造成這一問題的主要原因之一。因此,請(qǐng)嚴(yán)格的對(duì)待每一次的迭代,確保計(jì)劃已經(jīng)完成、確保軟件的質(zhì)量、確保用戶的需求得到滿足,這樣才是正統(tǒng)的迭代之路。
單次的迭代
我們說,每一次的迭代其實(shí)是一個(gè)完整的小過程。也就是說,它同樣要經(jīng)歷文章中討論的這些過程模式。只不過,這些模式的工作量都不大,你甚至可以在很短的時(shí)間內(nèi)做完所有的事情。因此,我們好像又回到了文章的開頭,重新討論架構(gòu)設(shè)計(jì)的過程。
單次迭代最令我們興奮的就是我們總是可以得到一個(gè)在當(dāng)前迭代中相當(dāng)穩(wěn)定的結(jié)果,而不像普通的架構(gòu)設(shè)計(jì)那樣,我們深怕架構(gòu)會(huì)出現(xiàn)問題,但又不得不依賴這個(gè)架構(gòu)。從心理上來(lái)分析,我們是在持續(xù)的建設(shè)架構(gòu)中,不需要回避需求的變更,因?yàn)槲覀兿嘈牛谛枨笙鄬?duì)應(yīng)的迭代中,會(huì)繼續(xù)對(duì)架構(gòu)進(jìn)行改進(jìn)。大家不要認(rèn)為這種心理的改變是無(wú)關(guān)緊要的,我起初并沒有意識(shí)到這個(gè)問題,但是我很快發(fā)現(xiàn)新的架構(gòu)設(shè)計(jì)過程仍然籠罩在原先的懼怕改變的陰影之下的時(shí)候,迭代設(shè)計(jì)很容易就退化為"Code and Fix"的情形。開發(fā)人員難以接受新方法的主要原因還是在心理上。因此,我不得不花了很多的時(shí)間來(lái)和開發(fā)人員進(jìn)行溝通,這就是我現(xiàn)實(shí)的經(jīng)驗(yàn)。
迭代的交錯(cuò)
基于我們對(duì)運(yùn)籌學(xué)的一點(diǎn)經(jīng)驗(yàn),迭代設(shè)計(jì)之間肯定不是線性的關(guān)系。這樣說的一個(gè)原因架構(gòu)設(shè)計(jì)和后續(xù)的工作間還是時(shí)間差的。因此,我們不會(huì)傻到把時(shí)間浪費(fèi)在等待其它工作上。一般而言,當(dāng)下一次迭代的需求開始之后,詳細(xì)需求開始之前,我們就已經(jīng)可以開始下一次迭代的架構(gòu)設(shè)計(jì)了。
各次迭代之間的時(shí)間距離要視項(xiàng)目的具體情況而定。比如,人員比較緊張的項(xiàng)目中,主要的架構(gòu)設(shè)計(jì)人員可能也要擔(dān)任編碼人員的角色,下一次迭代的架構(gòu)設(shè)計(jì)就可能要等到編碼工作的高峰期過了之后。可是,多次的交錯(cuò)迭代就可能產(chǎn)生版本的問題。比如,本次的迭代的編碼中發(fā)現(xiàn)了架構(gòu)的一個(gè)問題,反饋給架構(gòu)設(shè)計(jì)組,但是架構(gòu)設(shè)計(jì)組已經(jīng)根據(jù)偽修改的本次迭代的架構(gòu)開始了下一次迭代的架構(gòu)設(shè)計(jì),這時(shí)候就會(huì)出現(xiàn)不同的設(shè)計(jì)之間的沖突問題。這種情況當(dāng)然可以通過加強(qiáng)對(duì)設(shè)計(jì)模型的管理和引入版本控制機(jī)制來(lái)解決,但肯定會(huì)隨之帶來(lái)管理成本上升的問題,而這是不符合敏捷的思想的。這時(shí)候,團(tuán)隊(duì)設(shè)計(jì)就體現(xiàn)了他的威力了,這也是我們?cè)趫F(tuán)隊(duì)設(shè)計(jì)中沒有提到的一個(gè)原因。團(tuán)隊(duì)設(shè)計(jì)通過完全的溝通,可以解決架構(gòu)設(shè)計(jì)中存在沖突的問題。
迭代頻率
XP提倡迭代周期越短越好(XP建議為一到兩周),這是個(gè)不錯(cuò)的提議。在這么短的一個(gè)迭代周期內(nèi),我們花在架構(gòu)設(shè)計(jì)上的時(shí)間可能就只有一兩個(gè)小時(shí)到半天的時(shí)間。這時(shí)候,會(huì)有一個(gè)很有意思的現(xiàn)象,你很難去區(qū)分架構(gòu)設(shè)計(jì)和設(shè)計(jì)的概念了。因?yàn)樵谶@么短的一個(gè)周期之內(nèi),完成的需求數(shù)量是很少的,可能就只有一兩個(gè)用例或用戶素材。因此,這幾項(xiàng)需求的設(shè)計(jì)是不是屬于架構(gòu)設(shè)計(jì)呢?如果是的話,由于開發(fā)過程是由多次的迭代組成的,那么開發(fā)過程中的設(shè)計(jì)不都屬于架構(gòu)設(shè)計(jì)了嗎?我們說,架構(gòu)是一個(gè)相對(duì)的概念,是針對(duì)范圍而言的,在傳統(tǒng)的瀑布模型中,我們可以很容易的區(qū)分出架構(gòu)設(shè)計(jì)和普通設(shè)計(jì),如果我們把一次迭代看作是一個(gè)單獨(dú)的生命周期,那么,普通的設(shè)計(jì)在這樣一個(gè)范圍之內(nèi)也就是架構(gòu)設(shè)計(jì),他們并沒有什么兩樣。但是,迭代周期中的架構(gòu)設(shè)計(jì)是要遵循一定的原則的,這我們?cè)谙旅孢€會(huì)提到。
我們希望迭代頻率越快越好,但是這還要根據(jù)現(xiàn)實(shí)的情況而定。比如數(shù)據(jù)倉(cāng)庫(kù)項(xiàng)目,在項(xiàng)目的初期階段,我們不得不花費(fèi)大量的時(shí)間來(lái)進(jìn)行數(shù)據(jù)建模的工作,這其實(shí)也是一項(xiàng)專門針對(duì)數(shù)據(jù)的架構(gòu)設(shè)計(jì),建立元數(shù)據(jù),制定維,整理數(shù)據(jù),這樣子的過程很難分為多次的迭代周期來(lái)實(shí)現(xiàn)。
如何確定軟件的迭代周期
可以說,如果一支開發(fā)團(tuán)隊(duì)沒有相關(guān)迭代的概念,那么這支團(tuán)隊(duì)要立刻實(shí)現(xiàn)時(shí)隔兩周迭代周期是非常困難的,,同時(shí)也是毫無(wú)意義的。就像我們?cè)谏厦嬗懻摰?,影響迭代周期的因素很多,以至于我們那無(wú)法對(duì)迭代周期進(jìn)行量化的定義。因此我們只能從定性的角度分析迭代周期的發(fā)展。
另一個(gè)了解迭代的方法是閱讀XP的相關(guān)資料,我認(rèn)為XP中關(guān)于迭代周期的使用是很不錯(cuò)的一種方法,只是他強(qiáng)調(diào)的如此短的迭代周期對(duì)于很多的軟件團(tuán)隊(duì)而言都是難以實(shí)現(xiàn)的。
迭代周期的引入一定是一個(gè)從粗糙到精確的過程。迭代的本質(zhì)其實(shí)是短周期的計(jì)劃,因此這也是迭代周期越短對(duì)我們?cè)接泻锰幍囊淮笤?,因?yàn)闀r(shí)間縮短了,計(jì)劃的可預(yù)測(cè)性就增強(qiáng)了。我們知道,計(jì)劃的制定是依賴于已往的經(jīng)驗(yàn),如果原先我們沒有制定計(jì)劃或細(xì)節(jié)計(jì)劃的經(jīng)驗(yàn),那么我們的計(jì)劃就一定是非常粗糙,最后的誤差也一定很大。但是這沒有關(guān)系,每一次的計(jì)劃都會(huì)對(duì)下一次的計(jì)劃產(chǎn)生正面的影響,等到經(jīng)驗(yàn)足夠的時(shí)候,計(jì)劃將會(huì)非常的精確,最后的誤差也會(huì)很小。
迭代周期的確定需要依賴于單位工作量。單位工作量指的是一定時(shí)間內(nèi)你可以量化的最小的績(jī)效。最簡(jiǎn)單的單位工作量是每位程序員一天的編碼行數(shù)??上э@示往往比較殘酷,團(tuán)隊(duì)中不但有程序員的角色,還有設(shè)計(jì)師、測(cè)試人員、文檔制作人員等角色的存在,單純的編碼行數(shù)是不能夠作為的統(tǒng)計(jì)依據(jù)的。同樣,只強(qiáng)調(diào)編碼行數(shù),也會(huì)導(dǎo)致其它的問題,例如代碼質(zhì)量。為了保證統(tǒng)計(jì)的合理性,比較好的做法是一個(gè)團(tuán)隊(duì)實(shí)現(xiàn)某個(gè)功能所花費(fèi)的天數(shù)作為單位工作量。這里討論的內(nèi)容實(shí)際是軟件測(cè)量技術(shù),如果有機(jī)會(huì)的話,再和大家探討這個(gè)問題。