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