自20世紀(jì)50年代開始軟件開發(fā)以來,人們一直在探索軟件開發(fā)的方法。中培課堂專家王老師指出,目前,軟件開發(fā)過程一般被劃分為若干個(gè)目的和作用相對(duì)獨(dú)立活動(dòng),包括:需求、分析、設(shè)計(jì)、實(shí)現(xiàn)、測(cè)試和集成,以及維護(hù)。圍繞著如何安排、規(guī)劃這些活動(dòng)的次序、周期和歷時(shí),人們提出過各種各樣的軟件開發(fā)方法模型。
我們將具有以下特點(diǎn)的軟件開發(fā)方法定義為傳統(tǒng)軟件開發(fā)方法:
l 以預(yù)測(cè)性為原則
l 以文檔驅(qū)動(dòng)開發(fā)過程
l 以過程控制為核心
面對(duì)激烈的市場(chǎng)競(jìng)爭(zhēng),要求持續(xù)滿足不斷變化的需求,傳統(tǒng)軟件開發(fā)方法的特點(diǎn)也成為了它的弊病,應(yīng)對(duì)下面各種挑戰(zhàn)時(shí)顯得力不從心:
l 如何減少開發(fā)過程中的浪費(fèi)
l 如何準(zhǔn)確,及時(shí)的適應(yīng)需求變更
l 如何持續(xù)演進(jìn)系統(tǒng)架構(gòu)
l 如何保證軟件系統(tǒng)的長(zhǎng)期質(zhì)量
l 如何實(shí)現(xiàn)安全重構(gòu)(Refactoring)
l 如何最大限度的降低系統(tǒng)集成的成本
l 如何在團(tuán)隊(duì)中共享知識(shí),使團(tuán)隊(duì)成員共同成長(zhǎng)
l 如何合理的進(jìn)行成本和時(shí)間估算
l 如何迅速獲得軟件開發(fā)收益
在傳統(tǒng)軟件工程方法中,軟件開發(fā)的生命周期固定的劃分為若干順序的階段(需求、分析、設(shè)計(jì)、實(shí)現(xiàn)、集成測(cè)試和維護(hù)),如下圖所示。整個(gè)流程的特點(diǎn)是:
l 不完成上一個(gè)階段就不能進(jìn)入下一個(gè)階段
l 直到流程中期的開發(fā)階段(Implementation)才開始真正的編碼;之前所有階段的“成果”均以文檔形式體現(xiàn)
l 測(cè)試和集成(Testing and Integration)被認(rèn)為是對(duì)開發(fā)階段的輔助或者收尾,往往晚于開發(fā)階段開始
l 維護(hù)階段成本高昂
下面主要從需求分析,設(shè)計(jì),實(shí)現(xiàn)和維護(hù)四方面來分析傳統(tǒng)開發(fā)模式的問題。
1. 需求分析
傳統(tǒng)需求分析一般以名為“需求規(guī)格說明書”(Requirement Specification)的文檔為目標(biāo),以固定時(shí)長(zhǎng)(根據(jù)項(xiàng)目規(guī)模而定,一般2、3周或者更長(zhǎng))為約束,以完成需求文檔為結(jié)束。
經(jīng)歷過傳統(tǒng)需求分析過程的分析師和開發(fā)人員都會(huì)有類似的感覺:
l 無論用多長(zhǎng)時(shí)間來分析需求,總感覺需求沒有完備
l 無論如何研討,已有的需求總感覺不能百分之百明確
l 至項(xiàng)目開發(fā)后期,業(yè)務(wù)部門和技術(shù)部門往往就需求產(chǎn)生糾紛,一般有兩種形式:
1. 技術(shù)部門認(rèn)為頻繁的需求變更不但增加項(xiàng)目壓力,更使已有開發(fā)工作浪費(fèi)
2. 業(yè)務(wù)部門認(rèn)為軟件系統(tǒng)不能跟進(jìn),影響業(yè)務(wù)發(fā)展
傳統(tǒng)需求困境分析
造成上述傳統(tǒng)需求分析方法困境的原因主要有兩點(diǎn):
l 在項(xiàng)目進(jìn)行的過程中,業(yè)務(wù)需求本身也在發(fā)展變化,從而引發(fā)軟件需求變化。
l 業(yè)務(wù)人員不可能憑空把所有需求都想清楚,只有看到、用到真實(shí)的軟件之后,才能逐漸把自己的需求弄清楚。
雖然一次性需求存在諸多問題,但現(xiàn)實(shí)中,技術(shù)部門和業(yè)務(wù)部門往往都希望能在這個(gè)階段將所有問題想清楚。促使團(tuán)隊(duì)這樣做的深層原因在于:
l 從管理的角度考慮,軟件項(xiàng)目需要申請(qǐng)預(yù)算
l 從軟件開發(fā)的角度考慮,需求的每一次變更都需要長(zhǎng)的時(shí)間和巨大的成本來應(yīng)對(duì),這是技術(shù)部門和業(yè)務(wù)部門雙方都不愿看到的。為了避免項(xiàng)目中進(jìn)行可能的風(fēng)險(xiǎn),雙方都寧可在項(xiàng)目初期盡量把需求凍結(jié)。
第一個(gè)原因與項(xiàng)目計(jì)劃方式有關(guān);第二個(gè)原因與其說是對(duì)策,不如說是對(duì)傳統(tǒng)開發(fā)方法缺陷的妥協(xié):對(duì)企業(yè)級(jí)應(yīng)用系統(tǒng)來說,早期需求凍結(jié)不僅是無法做到,而且還會(huì)帶來一項(xiàng)隱性的浪費(fèi)——這種項(xiàng)目開發(fā)出來后,可能有20~30%的功能從上線開始,已經(jīng)不再需要;10~20%的功能的生命周期不超過半年,即費(fèi)用和人力有相當(dāng)一部分投入到無用的功能開發(fā)中。
業(yè)務(wù)部門和開發(fā)團(tuán)隊(duì)依賴文檔進(jìn)行溝通的后果往往是理解出現(xiàn)偏差,開發(fā)出的系統(tǒng)的不能滿足業(yè)務(wù)部門的真正需求,造成浪費(fèi)。
2. 設(shè)計(jì)
在傳統(tǒng)開發(fā)方法中,架構(gòu)設(shè)計(jì)是圍繞著設(shè)計(jì)文檔展開的。具體實(shí)施過程有如下特點(diǎn):
l 預(yù)先設(shè)計(jì)。在實(shí)際開發(fā)工作開始前,少數(shù)架構(gòu)師們需要用相當(dāng)長(zhǎng)的一段時(shí)間來進(jìn)行架構(gòu)設(shè)計(jì)和詳細(xì)設(shè)計(jì),力求得到一個(gè)具有高度可擴(kuò)展性的良好架構(gòu)。產(chǎn)出為“概要設(shè)計(jì)文檔”和“詳細(xì)設(shè)計(jì)文檔”。根據(jù)項(xiàng)目規(guī)模,這個(gè)過程一般持續(xù)數(shù)周、數(shù)月甚至數(shù)年不等
l 短暫評(píng)估。架構(gòu)師產(chǎn)出的設(shè)計(jì)文檔要經(jīng)過架構(gòu)設(shè)計(jì)評(píng)審委員會(huì)或類似組織的評(píng)審,這個(gè)過程一般持續(xù)數(shù)天
l 依據(jù)設(shè)計(jì)進(jìn)行實(shí)現(xiàn)。經(jīng)過評(píng)審的設(shè)計(jì)會(huì)交到開發(fā)者手中,進(jìn)行實(shí)際的編程實(shí)現(xiàn),這個(gè)過程往往以數(shù)月,甚至數(shù)年來計(jì)算。
思考傳統(tǒng)架構(gòu)設(shè)計(jì)方法,我們不禁要提出這樣的問題:
為什么傳統(tǒng)開發(fā)方法會(huì)如此重視前期預(yù)先架構(gòu)設(shè)計(jì),以至于希望在實(shí)際開發(fā)前把架構(gòu)設(shè)計(jì)做到盡善盡美?
答案在于,在傳統(tǒng)的概念中,一旦設(shè)計(jì)成型,架構(gòu)是很難調(diào)整的。例如,傳統(tǒng)的軟件工程教科書中都會(huì)討論“架構(gòu)調(diào)整的成本”問題:如果在設(shè)計(jì)中實(shí)現(xiàn)一次修改的成本為1;在實(shí)現(xiàn)過程中相同修改的成本就是5~10;在測(cè)試、部署階段,同樣的修改成本將上升到50~100;維護(hù)階段同樣修改的成本更是成指數(shù)曲線上升。
這種策略存在一個(gè)根本問題:軟件的“擴(kuò)展”究竟會(huì)如何發(fā)生是很難預(yù)計(jì)的。面對(duì)這一困境,傳統(tǒng)開發(fā)方法的解決方案是繼續(xù)增加預(yù)先設(shè)計(jì)的時(shí)間和人力,但往往收效甚微。
傳統(tǒng)設(shè)計(jì)困境分析
傳統(tǒng)預(yù)先設(shè)計(jì)方法惡性循環(huán)的原因有三點(diǎn),對(duì)應(yīng)上述實(shí)施過程的特點(diǎn):
l 設(shè)計(jì)和實(shí)現(xiàn)脫節(jié)。設(shè)計(jì)評(píng)審團(tuán)專家一般不參與實(shí)際的軟件開發(fā)。基于經(jīng)驗(yàn)的設(shè)計(jì)一方面無法得到實(shí)現(xiàn)的驗(yàn)證;另一方面,當(dāng)需求發(fā)生變更時(shí),無法隨之演進(jìn)。
l 評(píng)估的可靠性有限。對(duì)預(yù)先設(shè)計(jì)評(píng)估的只能基于已知的需求,而系統(tǒng)的可擴(kuò)展性是在應(yīng)對(duì)變更的需求時(shí)體現(xiàn)出來的,因此評(píng)估具有很大的局限性
l 實(shí)現(xiàn)者缺少對(duì)預(yù)先設(shè)計(jì)進(jìn)行修改的支持。當(dāng)預(yù)先設(shè)計(jì)不能滿足實(shí)際需求時(shí),開發(fā)者或者修改設(shè)計(jì),或者置需求變更不理,繼續(xù)沿預(yù)先設(shè)計(jì)開發(fā)。忽視需求變更的結(jié)果只能是系統(tǒng)無法滿足應(yīng)用(而開發(fā)者也可以將責(zé)任推到架構(gòu)師身上);如果開發(fā)者根據(jù)需求修改設(shè)計(jì),則預(yù)先設(shè)計(jì)不但事實(shí)上已經(jīng)成為浪費(fèi),而且已有的設(shè)計(jì)和實(shí)現(xiàn)往往更成會(huì)增加修改的難度。原因在于,如果預(yù)先設(shè)計(jì)的擴(kuò)展性沒有用到,則這些額外的擴(kuò)展性帶來的對(duì)當(dāng)前需求無用的復(fù)雜性,這些復(fù)雜性增加了理解、修改系統(tǒng)的難度。
3. 實(shí)現(xiàn)
軟件實(shí)現(xiàn)的質(zhì)量在某種程度上可以決定項(xiàng)目成敗。決定實(shí)現(xiàn)質(zhì)量的因素有兩個(gè):
l 缺陷(或稱為Bug)的數(shù)量
l 增加新功能的難易程度
無論開發(fā)者如何小心,隨著開發(fā)的不斷進(jìn)行,系統(tǒng)中缺陷的數(shù)量都在不斷積累。在傳統(tǒng)軟件開發(fā)方法中,測(cè)試往往被推遲到實(shí)現(xiàn)之后進(jìn)行,因而不斷積累的Bug不能被及時(shí)的發(fā)現(xiàn)和修復(fù)。這將帶來如下后果:
l 隨著Bug產(chǎn)生和發(fā)現(xiàn)之間的時(shí)間被延長(zhǎng),發(fā)現(xiàn)Bug原因的難度就更大
l Bug數(shù)量眾多,相互間的關(guān)系變得更為復(fù)雜,修復(fù)的成本就更高
l Bug修復(fù)的效果難以確認(rèn),往往修改一個(gè)地方,就有可能破壞其他功能點(diǎn),導(dǎo)致整個(gè)系統(tǒng)的BUG率長(zhǎng)時(shí)間不收斂
l Bug數(shù)量長(zhǎng)時(shí)間不收斂,開發(fā)團(tuán)隊(duì)逐漸失去信心,不敢再隨便修改,從而導(dǎo)致實(shí)現(xiàn)新需求的難度更大
l 迫于進(jìn)度壓力,技術(shù)部門不愿進(jìn)行更改,與業(yè)務(wù)部門的關(guān)系緊張
為了保證實(shí)現(xiàn)質(zhì)量,采用傳統(tǒng)開發(fā)方法的團(tuán)隊(duì)也做了很多努力,例如明文規(guī)定單元測(cè)試覆蓋率、定時(shí)進(jìn)行代碼復(fù)審等。但效果未必理想,一種情況是:由于實(shí)現(xiàn)和測(cè)試在實(shí)現(xiàn)時(shí)間上分離,測(cè)試運(yùn)行不及時(shí)、不頻繁,在進(jìn)度壓力下,這些制度往往不能真正落實(shí);另一種情況是:很多測(cè)試只是追求覆蓋率,沒有真正起到充分測(cè)試的作用,甚至出現(xiàn)假測(cè)試。代碼復(fù)審會(huì)議也流于形式,對(duì)于改進(jìn)代碼質(zhì)量的幫助不大。于是我們看到一個(gè)現(xiàn)象:一邊是公司不斷強(qiáng)調(diào)質(zhì)量管理,另一邊軟件還是Bug重重,代碼修改難度很大。由此可見,要保證軟件質(zhì)量,只有制度還是不夠的。
大型企業(yè)級(jí)應(yīng)用系統(tǒng)往往是由多個(gè)模塊或者子系統(tǒng)組成的,因此除了基本的開發(fā)活動(dòng),與系統(tǒng)質(zhì)量、成敗密切相關(guān)的另一個(gè)問題是集成。
傳統(tǒng)開發(fā)方法通常在開發(fā)結(jié)束之后才進(jìn)行系統(tǒng)集成和驗(yàn)收測(cè)試,這就導(dǎo)致這個(gè)階段成了一個(gè)問題高發(fā)階段。系統(tǒng)經(jīng)常在集成階段集成不起來,大量以前沒有預(yù)料到的BUG突然出現(xiàn),團(tuán)隊(duì)需要花費(fèi)很多時(shí)間來解決這些問題,給項(xiàng)目造成了很大的風(fēng)險(xiǎn)。有些項(xiàng)目,在開發(fā)實(shí)現(xiàn)階段感覺已經(jīng)接近結(jié)束了,但一到集成階段就問題重重,使得“上線”成了一件令人恐懼的辛苦工作,需要在客戶現(xiàn)場(chǎng)加班加點(diǎn)才能成功上線。再加上驗(yàn)收測(cè)試突然提出大量修改意見,愈發(fā)增加了這一階段的工作量和難度。
傳統(tǒng)實(shí)現(xiàn)方法困境分析
造成上述困境的主要原因是:
l 測(cè)試人員介入產(chǎn)品測(cè)試較晚,一方面導(dǎo)致,隨著系統(tǒng)的不斷增大,很多缺陷被埋藏的很深,很難發(fā)現(xiàn);另一方面,在接近發(fā)布的時(shí)點(diǎn)發(fā)現(xiàn)很多問題,留給開發(fā)人員修復(fù)的非常少,導(dǎo)致只能帶著缺陷發(fā)布
l 需求通過文檔傳遞,開發(fā)人員和測(cè)試人員理解常常有偏差。如果需求文檔更新不及時(shí),還會(huì)導(dǎo)致很多無效的工作
l 沒有自動(dòng)化的測(cè)試和持續(xù)集成環(huán)境的情況,集成和測(cè)試的成本很高,所以無法頻繁的進(jìn)行這種有效的質(zhì)量保證活動(dòng)
l 在開發(fā)過程中,開發(fā)人員更多考慮功能實(shí)現(xiàn),而忽視了代碼質(zhì)量、設(shè)計(jì)的優(yōu)化和可測(cè)試性,導(dǎo)致后期修改代碼成本很高
隨著人們對(duì)軟件開發(fā)認(rèn)識(shí)的加深,可測(cè)試性(testability)逐漸被提升到了開發(fā)活動(dòng)中第一要素的位置。而傳統(tǒng)軟件開發(fā)方法陷入困境的原因恰恰在于對(duì)可測(cè)試性的忽視。除了基本的驗(yàn)證功能的正確性,可測(cè)試還具有更深層次的含義:
l 可測(cè)試性是架構(gòu)設(shè)計(jì)的試金石。不可測(cè)試的系統(tǒng)往往模塊間依賴關(guān)系混亂,功能劃分不清晰,理解困難,導(dǎo)致出現(xiàn)Bug后難以發(fā)現(xiàn)原因,新需求也難以加入
l 從敏捷開發(fā)的角度看,測(cè)試還具有如下功能和目標(biāo):
1. 最準(zhǔn)確、可運(yùn)行的系統(tǒng)設(shè)計(jì)文檔
2. 測(cè)試驅(qū)動(dòng)系統(tǒng)設(shè)計(jì)
3. 自動(dòng)化測(cè)試更好的支持重構(gòu),從而使架構(gòu)演進(jìn)成為可能
在傳統(tǒng)開發(fā)方法中,代替自動(dòng)化測(cè)試的往往是大量的手工測(cè)試,這樣測(cè)試除了成本高、耗時(shí)長(zhǎng)外,還存在難以保證測(cè)試一致性和質(zhì)量,從而無法擔(dān)當(dāng)起保證軟件質(zhì)量的重任,更對(duì)架構(gòu)設(shè)計(jì)毫無貢獻(xiàn)。
4. 維護(hù)
隨著業(yè)務(wù)的發(fā)展,以及用戶對(duì)軟件系統(tǒng)的理解加深,新的情況會(huì)不斷涌現(xiàn)。
l 在日復(fù)一日使用過程中,一些在驗(yàn)收測(cè)試中沒有發(fā)現(xiàn)的缺陷也會(huì)浮現(xiàn)出來
l 隨著業(yè)務(wù)數(shù)據(jù)量的增加,系統(tǒng)對(duì)性能的要求也會(huì)比最初構(gòu)建是提高
l 開發(fā)和維護(hù)通常是不同的團(tuán)隊(duì),開發(fā)過程中很多的知識(shí)沒有被傳遞給維護(hù)人員
l 隨著市場(chǎng)的變化和客戶在使用中發(fā)現(xiàn)新的價(jià)值,新的需求會(huì)被提出
這些都對(duì)維護(hù) 提出了很高的要求。
傳統(tǒng)維護(hù)方法的困境
l 系統(tǒng)的靈活性較差,較大范圍的調(diào)整和新增功能困難
l 沒有得到及時(shí)更新的文檔不能反映系統(tǒng)的真實(shí)情況,即使文檔內(nèi)容正確,單純通過文檔很難真正理解一個(gè)系統(tǒng)
l 人員的變更對(duì)系統(tǒng)的影響很大
如果不能及時(shí)的對(duì)客戶的要求進(jìn)行響應(yīng),會(huì)降低客戶滿意度,使客戶喪失很多市場(chǎng)的機(jī)會(huì)。