系統分析與設計方法---需求分析與軟體設計
需求分析是軟體生命週期中相當重要的一個階段。根據 Standish Group 對 23000 個專案進行的研究結果表明,28%的專案徹底失敗,46%的專案超出經費預算或者超出工期,只有約 26%的專案獲得成功。需求分析工作在整個軟體開發生命週期中有著十分重要的意義。而在這些高達 74%的不成功專案中,有約 60%的失敗是源於需求問題,也就是差不多有一半的專案都遇到了這個問題,這一可怕的現象引起人們對需求分析的高度重視。需求分析階段的主要任務是通過開發人員與使用者之間的廣泛交流,不斷澄清一些模糊的概念,最終形成一個完整的、清晰的、一致的需求說明。
而當明確了使用者的需求之後,下一步的任務就是對未來的軟體系統進行設計,它是確定系統實現的關鍵工作。需求分析和設計的方法對軟體開發過程而言是十分重要的,因此必須紮實地掌握它。
需求分析與軟體設計是軟體生存期中最重要的兩個步驟,需求分析解決的是“做什麼” 的問題,系統設計則是解決“怎麼做”的問題。
1 需求分析的任務與過程
需求分析所要做的工作是深入描述軟體的功能和效能,確定軟體設計的限制和軟體同其他系統元素的介面細節,定義軟體的其他有效性需求,細化軟體要處理的資料域。用一句話概括就是:需求分析主要是確定待開發軟體的功能、效能、資料、介面等要求。需求分析的實現步驟通常包括:獲取當前系統的物理模型,抽象出當前系統的邏輯模型,建立目標系統的邏輯模型三個部分。具體來說,需求分析階段的工作可以分成 4 個方面:
(1)問題識別:用於發現需求、描述需求,主要包括功能需求、效能需求、環境需求、可靠性需求、安全保密需求、使用者介面需求、資源使用需求、軟體成本消耗與開發進度需求,以此來預先估計以後系統可能達到的目標。
(2)分析與綜合:也就是對問題進行分析,然後在此基礎上整合出解決方案。這個步驟經常是反覆進行的,常用的方法有面向資料流的結構化分析方法(Structured Analysis, SA),面向資料結構的 Jackson 方法,面向物件的分析方法(Object Oriented Analysis,OOA),以及用於建立動態模型的狀態遷移圖和 Petri 網。
(3)編制需求分析的文件:也就是對已經確定的需求進行文件化描述,該文件通常稱為“需求規格說明書”。
(4)需求分析與評審:它是需求分析工作的最後一步,主要是對功能的正確性、完整性和清晰性,以及其他需求給予評價。
1.需求的分類
什麼是軟體的需求呢?軟體需求就是系統必須完成的事及必須具備的品質。具體來說,軟體需求包括功能需求、非功能需求和設計約束三方面內容。各種需求的概念示意圖如圖 8-4 所示。
-
功能需求:是指系統必須完成的那些事,即為了向它的使用者提供有用的功能,產品必須執行的動作。
-
非功能需求:是指產品必須具備的屬性或品質,如效能、響應時間、可靠性、容錯性、擴充套件性等。
-
設計約束:也稱為限制條件、補充規約,這通常是對解決方案的一些約束說明,例如必須採用國有自主知識版權的資料庫系統,必須在 UNIX 作業系統之下執行等。
除了這三種需求之外,還有業務需求、使用者需求、系統需求這三個處於不同層面的概念,充分地理解這樣的模型才能夠更加清晰地理清需求的脈絡。
-
業務需求(Business Requirement):是指反映組織機構或客戶對系統、產品高層次的目標要求,通常問題定義本身就是業務需求。
-
使用者需求(User Requirement):是指描述使用者使用產品必須要完成什麼任務,怎麼完成的需求,通常是在問題定義的基礎上進行使用者訪談、調查,對使用者使用的場景進行整理,從而建立從使用者角度出發的需求。
-
系統需求(System Requirement):是從系統的角度來說明軟體的需求,它包括用特性說明的功能需求、質量屬性、非功能需求及設計約束。
分析師經常圍繞著“功能需求”來展開工作,而功能需求大部分都是從“系統需求” 的角度來分析與理解的,也就是用“開發人員”的視角來理解需求。但要想真正地得到完整的需求,僅戴上“開發人員”的眼鏡是不夠的,還需要“領域專家”的眼鏡,要從更高的角度來理解需求,這就是“業務需求”;同時還應該更好地深入使用者,瞭解他們的使用場景,瞭解他們的想法,這就是“使用者需求”。這是一個理解層次的問題,並不僅僅是簡單的概念。
2.需求工程
需求工程就是包括建立和維護系統需求文件所必需的一切活動的過程,主要包括需求
開發和需求管理兩大工作。
(1)需求開發:包括需求捕獲、需求分析、編寫規格說明書和需求驗證 4 個階段。在這個階段需要完成確定產品所期望的使用者型別、獲取每種使用者型別的需求、瞭解實際使用者任務和目標及這些任務所支援的業務需求、分析源於使用者的資訊、對需求進行優先順序分類、將所收集的需求編寫成為軟體規格說明書和需求分析模型、對需求進行評審等工作。
(2)需求管理:通常包括定義需求基線、處理需求變更、需求跟蹤等方面的工作。
這兩個方面是相輔相成的,需求開發是主線,是目標;需求管理是支援,是保障。換句話說,需求開發是努力更清晰、更明確地掌握客戶對系統的需求;而需求管理則是對需求的變化進行管理的過程。
3.需求分析方法
需求分析的方法可謂種類繁多,不過如果按照分解方式的不同,可以很容易地劃分出幾種型別。本節先從分析方法發展的歷史,對其建立一個概要性的認識,在本章的後面幾節中將詳細說明最具有代表性的結構化分析與設計、面向物件分析與設計兩種方法。
(1)結構化分析方法:最初的分析方法都不成體系,而且通常都只包括一些籠統的告誡,在20 世紀 70 年代分析技術發展的分水嶺終於出現了。這時人們開始嘗試使用標準化的方法,開發和推出各種名為“結構化分析”的方法論,而 Tom DeMacro 則是這個領域最有代表性和權威性的專家。
(2)軟系統方法:這是一個過渡性的方法論,並未真正流行過,它的出現只是證明了結構化分析方法的一些不足。因為結構化分析方法採用的相對形式化的模型不僅與社會觀格格不入,而且在解決“不確定性”時顯得十分無力。最有代表性的軟系統方法是 Checkland 方法。
(3)面向物件分析方法:在 20 世紀 90 年代,結構化方法的不足在面對多變的商業世界時,顯得更加蒼白無力,這就催使了 OOA 的迅速發展。
(4)面向問題域的分析(Problem Domain Oriented Analysis,PDOA):現在又發現面向物件分析方法也存在著很多的不足,應運而生了一些新的方法論,PDOA 就是其中一種。不過現在還在研究階段,並未廣泛應用。
2 如何進行系統設計
當設計者拿到一個需求,他如何開展系統設計呢?許多想進入系統分析與設計的年輕人以為自己知道了面向物件、統一建模語言、設計模式等新鮮深奧的名詞就可以進行設計了,可是掌握工具和技能絕不是成為優秀設計者的充分條件,甚至也不是必要條件。遺憾的是這裡沒有捷徑,只有設計者在實踐中不斷學習和總結。而在實踐中,系統設計與其說是在設計,不如說是在選擇和妥協。
妥協,就是在各個系統目標之間找到一個平衡點。系統目標包括但不限制於功能、效能、健壯性、開發週期、交付日期等。不幸的是,這些目標往往是矛盾的,提高軟體效能直接意味著開發週期的增加、交付日期的推遲,盲目地增加功能可能導致效能降低,維護成本提高。軟體設計者的難題在於在如此眾多的目標之間找到這個平衡點,並且明確知道如何設計能實現這個平衡,既可以讓投資者覺得在預算之內,又能讓使用者相對滿意。可行性分析階段應該已經論述了這樣一個平衡點,可是如果設計者發現沒有這樣一個平衡點,如同沒有一個設計者能讓人騎著自行車到月球上去,那麼設計者只能提出放棄某個方面的過度要求,否則系統要遭受必然失敗的命運。更多的情況是沒有經驗的設計者不知道是否存在這些平衡點,更不知道如何利用合理的設計及有效的工具來達到平衡。因此設計者需要了解可以解決問題的各種方案,並清楚知道各個方案的效果、成本、缺點,以及這些方案的區別,並在各種方案中進行選擇。而這些,不是一個人能在一兩天瞭解的。
沒有一個設計者會完全重新開始設計一個系統,他們總參考多個與目標系統相類似的系統,再從中進行甄別、取捨和補充來作為新系統的設計。人們發現一個優秀的設計者似乎能在聽完需求後就立即構想出目標系統的框架,這並不是因為他聰明或者比不知所措的設計者新手多一個腦袋,而是因為他在平時已經瞭解大量的系統,對各種設計的優缺點、侷限性也瞭然於胸,能夠把以前的設計根據需要再次使用。所以要成為優秀的設計者,瞭解、掌握、消化、總結前人和自己以前的設計成果是最好的方法,這似乎也是唯一的方法。
設計者的苦惱有時候和程式設計人員一樣。計算機系統的發展如此迅速,解決方案也越來越多,如同程式語言的發展,同時,隨著人類社會的進步,投資者和客戶也提出了越來越高的要求,這又需要設計者不斷學習、創造新的方案。
但系統設計也並非沒有規律可以遵循,如同幸福的家庭都很相似,不幸的家庭各有各的不幸,人們在實踐中發現優秀的系統設計一般在以下幾個方面都很出色。
(1)元件的獨立性。審視自己設計的系統,是否做到了高內聚、低耦合?
(2)例外的識別和處理。誰能保證系統使用者都精確按照使用說明書使用?
(3)防錯和容錯。當網路中斷、資料庫崩潰這樣的災難性事件發生時,系統也跟著崩潰嗎?
而且,更幸運的是,也有一些技術能夠改進系統設計,這些方法包括:降低複雜性、通過合約進行設計、原型化設計、錯誤樹分析等。
3 軟體設計的任務與活動
軟體設計是一個把軟體需求變換成軟體表示的過程。最初這種表示只是描繪出軟體的總體框架,然後再進一步細化,並在此框架中填入細節。
1.軟體設計的兩個階段從工程管理角度,軟體設計可以分為兩個步驟:
(1)概要設計:也稱為高層設計,將軟體需求轉化為資料結構和軟體的系統結構。例如,如果採用結構化設計,則將從巨集觀的角度將軟體劃分成各個組成模組,並確定模組的功能及模組之間的呼叫關係。
(2)詳細設計:也稱為低層設計,將對結構表示進行細化,得到詳細的資料結構與演算法。同樣的,如果採用結構化設計,則詳細設計的任務就是為每個模組進行設計。
2.主要的設計方法比較
在結構化設計風行的時代,主流的設計方法還包括 Jackson 方法和 Parnas 方法。結構化方法側重於“模組相對獨立且功能單一,使模組間聯絡弱、模組內聯絡強”;而 Jackson 方法則是從資料結構匯出模組結構;Parnas 方法的主要思想則是將可能引起變化的因素隱藏在有關模組內部,使這些因素變化時的影響範圍受到限制,它只提供了重要的設計準則,但沒有規定出具體的工作步驟。
而近年來,物件技術憑藉其對資料的高效封裝及良好的訊息機制,實現了高內聚、低耦合的系統設計,成了現代軟體設計的主流方法學。