2.3 結構化分析方法
結構化分析(Structural Analysis,SA)是由美國Yourdon公司提出的適用于分析典型數據處理系統的,以結構化的方式進行系統定義的分析方法。這個方法通常與L.Constantine 提出的結構化設計(Structural Design,SD)方法銜接起來使用,即所謂的 SA/SD 方法,也可稱為面向功能的軟件開發方法或面向數據流的軟件開發方法。SA/SD 方法首先用結構化分析(SA)對軟件進行需求分析,然后用結構化設計(SD)方法進行總體設計,最后是結構化編程(Structural Programming,SP)。結構化分析(SA)方法最初由Douglas Ross提出,由DeMarco推廣,由Ward、Mellor及后來的Hatley、Pirbhai擴充,形成了今天的結構化分析方法的框架。結構化分析方法是一種建模技術,它建立的分析模型,如圖2.6所示。

圖2.6 分析模型的結構
這種分析模型必須達3個主要目標:
(1)描述用戶要求。
(2)建立軟件設計的基礎。
(3)定義軟件開發完成時,必須確認的需求集合。
該模型的核心是數據詞典,它描述了所有在目標系統中使用的和生成的數據對象。圍繞這個核心有 3 種圖:實體—關系圖(Entity Relationship Diagram,ERD)描述數據對象及數據對象之間的關系;數據流程圖(DFD)描述數據在系統中如何被傳送或變換,以及描述如何對數據流進行變換的功能(子功能);狀態—遷移圖(State Transference Diagram,STD)描述系統對外部事件如何響應、如何動作。
因此,ERD用于數據建模,DFD用于功能建模,STD用于行為建模。
2.3.1 數據建模
數據模型包括數據對象、對象屬性、對象間關系 3 種互相關聯的信息。數據建模要回答與任何數據處理應用相關的一組特定問題,如系統處理哪些主要的數據對象,每個數據對象的組成如何,哪些屬性描述了這些對象,這些對象當前位于何處,每個對象與其他對象有哪些關系,對象和變換它們的處理之間有哪些關系。
1.數據對象
數據對象是需要被目標系統所理解的復合信息的表示,所謂復合信息是具有若干不同特征或屬性的信息。數據對象可以是外部實體(如顯示器)、事物(如報表或顯示)、角色(如教師或學生)、行為(如一個電話呼叫)或事件(如單擊鼠標左鍵)、組織單位(如研究生院)、地點(如注冊室)、結構(如文件)。
數據對象只封裝了數據,沒有包含作用于這些數據上的操作。這與面向對象開發方法中的類和對象不同。具有相同特征的數據對象組成的集合仍然稱為數據對象,其中的某一個對象稱為該數據對象的一個實例。
2.對象屬性
屬性定義了數據對象的特征。它可用來:
(1)為數據對象的實例命名。
(2)描述這個實例。
(3)建立對另一個數據對象的另一個實例的引用。
如學生數據對象的屬性可以有學號、姓名、性別、出生年月、籍貫等。為了唯一地標識數據對象的某個實例,定義數據對象中的一個屬性或幾個屬性為關鍵碼(key),書寫為Id,如在學生數據對象中用學號做關鍵碼,它可唯一地標識一個學生數據對象中的實例。
3.對象間關系
各個數據對象的實例之間可以按多種不同的方式相連接。如數據對象“書”與“書店”有關聯,可以用圖 2.7(a)的符號簡單表示。但考慮在待開發軟件的上下文環境中“書”與“書店”的關系,可以定義一組對象—關系對來定義相應的連接,如“書店訂購書”“書店陳列書”“書店儲存書”“書店銷售書”“書店返還書”,圖2.7(b)給出了這些對象—關系對的圖形表示。

圖2.7 對象間關系
4.基數和參與性
數據對象、屬性和關系是理解問題數據域的基礎。但僅有這些信息是不夠的,必須提供更進一步的有關數據對象關聯的信息。例如,學生“張鵬”選修“軟件工程”與“計算機網絡”兩門課程,學生與課程的實例通過“選修”關聯起來。實例的關聯有一對一(1∶1)、一對多(1∶m)、多對多(n∶m) 3種。這種實例的關聯稱為“基數”,基數表明了重復性。
例如,1名教師帶班級中的30名同學,就是1∶m的關系;但也有1名教師帶0名同學的情形。所以實例關聯有“可選”或“必須”之分,用“〇”表示關系是可選的,用“|”表示關系必須出現 1 次,這表明了“參與性”關系,如圖2.8所示。

圖2.8 基數與參與性
5.實體—關系圖
數據對象及其關系可用實體—關系圖(ERD)表示。ERD最初是由Peter Chen為關系數據庫提出來的,后來又經過了擴展。ERD的主要目的是表示數據對象及其關系,它包括數據對象、屬性、關系等基本成分和各種類型符號。圖2.9給出了學生選修課程的ERD及描述學生屬性的數據對象表。

圖2.9 簡單的ERD和數據對象表
數據建模方法用來創建部分分析模型,但它也可以用于設計數據庫并支持其他需求分析方法。
實體—關系圖的建立步驟如下:
(1)在捕獲需求的過程中,要求用戶列出應用或業務過程涉及的所有事物。這些事物將來可能會演變為一系列輸入/輸出數據對象,以及生產和消費信息的外部實體。
(2)一次考慮一個對象。分析人員和用戶共同確認這個對象與其他對象之間是否存在連接(在本階段不命名)。
(3)當存在連接時,分析人員和用戶應創建一個或多個對象—關系對。
(4)考察每個對象—關系對的基數和參與性。
(5)迭代執行步驟(2)~(4),直到所有對象—關系對定義完成。在這個過程中發生遺漏是很正常的,每次迭代總會增加新的對象和關系。
(6)定義每個實體的屬性。
(7)規范化并復審實體—關系圖。
(8)重復執行步驟(1)~(7),直到數據建模完成。
2.3.2 功能建模和數據流
最初,結構化分析方法僅討論數據流建模,目標系統被表示成如圖2.10所示的數據流程圖。系統的功能體現在核心的數據變換中,系統的輸入源于用方框表示的外部實體,這種輸入引發系統的數據變換,產生傳遞給外部實體的輸出。

圖2.10 數據流程圖
功能建模的思想就是用抽象模型的概念,按照軟件內部數據傳遞、變換的關系,自頂向下逐層分解,直到找到滿足功能要求的所有可實現的軟件為止。根據DeMarco的論述,功能模型使用了數據流程圖來表達系統內數據的運動情況,而數據流的變換則用結構化語言、判定表與判定樹來描述。
1.數據流程圖
結構化分析的核心部分是數據流程圖(Data Flow Diagram,DFD)。數據流程圖是一種用來表示信息流程和信息變換過程的圖解方法,它把系統看成由數據流聯系的各種功能的組合。在需求分析中用它來建立現存或目標系統的數據處理模型,當數據流程圖用于軟件需求分析時,這些處理或轉換,在最終生成的程序中將是若干個程序功能模塊。圖 2.11 所示為會計賬務處理系統的數據流程圖。

圖2.11 會計賬務處理系統的數據流程圖
數據流程圖包括 4 種基本成分,分別用 4 種基本符號表示,如圖 2.12所示。

圖2.12 數據流程圖的基本符號
從圖2.11可以看出數據流有原始憑證、會計報表、記賬憑證、賬簿等。數據存儲包括記賬憑證和賬簿信息。加工處理有編制記賬憑證、登賬處理和編制報表。而源點和終點則是往來單位、企業職工和上級部門。
(1)數據流。數據流是描繪數據流程圖中各種成分的接口。數據流的方向可以從加工流向加工;從加工流向數據存儲;從數據存儲流向加工;從源點流向加工或從加工流向終點。數據流的含義如下:
① 數據流是一組成分已知的信息包。信息包中可以有一個或多個已知信息。
② 兩個加工間可以有多個數據流,當數據流之間毫無關系,也不是同時流出時,如果強制合成一個數據流,則會使問題更為含糊不清。
③ 數據流應有良好的名字,它不僅作為數據的標識,而且有利于深化對系統的認識,便于進一步了解系統。
④ 同一數據流可以流向不同的加工,不同的加工可以流出相同的流(合并與分解)。
⑤ 流入或流出到存儲的數據流不需要命名,因為數據存儲的名字已經有足夠的信息來表達數據流的意義。
⑥ 數據流不代表控制流。數據流反映了處理的對象,控制流是一種用來選擇或影響加工的性質,而不是對它進行加工的對象。
(2)數據加工。數據加工是對數據執行某種操作或變換,是把輸入數據變成輸出數據流的一種變換。每個加工應有一個名字來概括、代表它的意義。(3)數據存儲。數據存儲并不等同于一個文件,它可以表示文件、文件的一部分、數據庫的元素或記錄的一部分等。數據可以存儲在磁盤、磁帶、存儲器和其他介質上。應該認真對數據文件進行命名。在數據流程圖中,要注意指向數據文件箭頭的方向,讀數據的箭頭是指向加工處理的;寫數據的箭頭是指向數據存儲的;如果既有讀又有寫,則是雙向箭頭。
(4)源點和終點。源點和終點代表系統之外的人、物或組織。它們發出或接收系統的數據,使用起來不嚴格,其作用是提供系統和外界環境之間關系的注釋性說明。一般來說,表示一個系統只要有數據流、加工和文件就夠了。但是為了有助于理解,有時可以加上數據流的源點和終點,以此說明數據的來龍去脈,使數據流程圖更加清晰。而源與源之間的關系則不予考慮。
畫數據流程圖的方法是:首先識別出主要輸入、輸出;然后從輸入向輸出推進,找出通道上的主要變換。在大多數情況下,原則上是由外向里、自頂向下去模擬問題的處理過程,通過一系列的分解步驟,逐步求精地表達出整個系統功能的內部關系。
畫數據流程圖的步驟如下:
步驟1 在圖的邊緣標出系統的輸入、輸出數據流,從而決定研究的內容和系統的范圍。
步驟2 畫出數據流程圖的內部。將系統的輸入、輸出用一系列處理連接起來,可以從輸入數據流畫向輸出數據流,或從中間畫出。
步驟3 仔細為數據流命名。
步驟4 根據加工的輸入、輸出內容,為加工命名——“動詞+賓語”。
步驟5 不考慮初始化和終點,暫不考慮出錯路徑等細節,不畫控制流和控制信息。
步驟6 反復與檢查。思維過程是一種迭代的過程。
應該指出,在需求分析階段中的數據處理并不一定是一個程序或程序模塊,而是反映了系統的功能。如何實現,就要考慮在一定約束條件下軟件設計方案的選擇和編程問題。另外,它除了代表計算機處理過程,還可以代表人工處理過程,如由專業人員對輸入的數據進行正確性檢查等。類似地,一個數據的存儲也不一定代表一個實際文件,實際數據可以存儲在包括人腦在內的任何介質上。
2.分層數據流程圖
為了表達數據處理過程的數據加工情況,用一個數據流程圖是不夠的。稍為復雜的實際問題,在數據流程圖上常常出現十幾個甚至幾十個加工。這樣的數據流程圖看起來很不清楚,層次結構的數據流程圖能很好地解決這一問題。按照系統的層次結構進行逐步分解,并以分層的數據流程圖反映這種結構關系,能清楚地表達和理解整個系統。
圖2.13為分層數據流程圖示例,數據處理S包括3個子系統1、2、3。頂層下面的第 1 層數據流程圖為 DFD/L1,第 2 層數據流程圖 DFD/L2.1、DFD/L2.2及DFD/L2.3分別是子系統1、2和3的細化。對任何一層數據流程圖來說,我們稱它的上層圖為父圖,在它下一層的圖則稱為子圖。

圖2.13 分層數據流程圖示例
在多層數據流程圖中,需要區分頂層流圖、底層流圖和中間層流圖。頂層流圖僅包含一個加工,它代表被開發系統。它的輸入流是該系統的輸入數據,輸出流是系統的輸出數據。頂層流圖的作用在于表明被開發系統的范圍,以及它和周圍環境的數據交換關系,為逐層分解打下基礎。底層流圖是指其加工不需要再做分解的數據流程圖,它處在最底層,有時也稱其加工為原子加工。中間層流圖則表示對其上層父圖的細化,它的每個加工可能繼續細化,形成子圖,中間層的多少視系統的復雜程度而定。
畫數據流程圖的基本步驟概括地說,就是自外向內,自頂向下,逐層細化,完善求精:
(1)首先確定系統的輸入和輸出,以反映系統與外界環境的接口。
(2)第0層數據流程圖將軟件系統描述為一個加工,以反映最主要的業務處理流程,它代表系統本身。但它并未明確表達數據加工的要求,需要進一步細化。
(3)從輸入端開始,根據系統業務工作流程,畫出數據流流經的各加工框,以反映數據的實際處理過程,逐步畫到輸出端,得到第1層數據流程圖。圖中的加工分別編號。
(4)細分每個加工框。如果加工框內還有數據流,可將這個加工框再細分成幾個子加工框,并在各子加工框之間畫出數據流。
(5)一次細化一個加工。數據流程圖的細化可以連續進行,直到每個加工只執行一個簡單操作為止。就是說,直到每個加工執行一個可以用程序實現的功能為止。
檢查和修改數據流程圖的原則如下:
(1)數據流程圖上所有圖形符號只限于前述4種基本圖形元素。
(2)頂層數據流程圖必須包括前述4種基本元素,缺一不可。
(3)頂層數據流程圖上的數據流必須封閉在外部實體之間。
(4)每個加工至少有一個輸入數據流和一個輸出數據流。
(5)在數據流程圖中,需要按層給加工框編號。編號表明該加工處在哪一層,以及上下層父圖與子圖的對應關系。
(6)規定任何一個數據流子圖必須與它上一層的一個加工對應,兩者的輸入數據流和輸出數據流必須一致,此即父圖與子圖的平衡。
(7)可以在數據流程圖中加入物質流,幫助用戶理解數據流程圖。
(8)圖上每個元素都必須有名字。數據流和數據文件的名字應當是名詞或名詞性短語,表明流動的數據是什么。加工的名字應當是名詞+賓語,表明做什么事情。
(9)數據流程圖中不可夾帶控制流,整個圖不反映加工的執行順序。
(10)初畫時可以忽略瑣碎的細節,以集中精力于主要數據流。
父圖與子圖的平衡是分層數據流程圖中的重要性質,它保證了數據流程圖的一致性,避免分析出錯,也便于分析人員閱讀和理解。特別地,當某一層數據流程圖中的數據存儲對象不是父圖相應加工的數據接口,而只是本層數據流程圖中某些加工之間的數據接口時,這樣的數據存儲應是局部數據存儲。只有當局部數據存儲作為某些數據加工之間的數據接口或某個特定加工的輸入/輸出時,才把它畫出來,這樣做有利于實現信息隱蔽。
3.加工規格說明
加工規格說明用來說明DFD中數據加工的加工細節。加工規格說明描述了數據加工的輸入、實現加工的算法及產生的輸出。另外,加工規格說明指明了加工(功能)的約束和限制、與加工相關的性能要求,以及影響加工實現方式的設計約束。必須注意,寫加工規格說明的主要目的是要表達“做什么”,而不是“怎么做”。因此它應描述數據加工實現加工的策略而不是實現加工的細節。目前用于寫加工規格說明的工具有程序設計語言、判定表和判定樹。
1)程序設計語言
程序設計語言(Program Design Language,PDL)也稱為結構化語言,它是一種介于自然語言和形式化語言之間的半形式化語言。它是在自然語言基礎上加了一些限制而得到的語言,它使用有限的詞匯和有限的語句來描述加工邏輯。一般來說,對于順序執行和循環執行的動作,用結構化語言描述;對于存在多個條件復雜組合的判斷問題,用判定表和判定樹。
結構化語言的結構分為外層和內層,外層用來描述語言正文。它將語言正文用基本控制結構進行分割,基本控制結構包括簡單陳述句結構、判定結構(IF_THEN_ELSE_ENDIF或CASE_OF_ENDCASE)和重復結構(WHILE_DO或REPEAT_UNTIL)3種。
內層一般采用祈使語句的自然語言短語,使用數據詞典中定義的名字和有限的自定義詞。其動詞含義要具體,盡量不用形容詞和副詞來修飾,還可以使用一些簡單的算術運算和邏輯運算符號。
此外在書寫時,必須按層次橫向向右移行,續行也同樣向右移行,對齊。下面是某商店業務處理系統中“檢查發貨單”的例子。

2)判定表(Decision Table)
在某些問題中,數據流程圖中某個加工的一組動作依賴于多個邏輯條件的取值,就是說完成這一加工的一組動作是由于某一組條件取值的組合引發的。這時使用判定表來描述比較合適,它可以清楚地表示復雜的條件組合與應做動作之間的對應關系。
下面以檢查發貨單為例,說明判定表的構成,如圖2.14所示。

圖2.14 檢查發貨單的判定表圖
判定表由4個部分組成,如圖2.15所示。雙線分割開的4個部分是條件茬、動作茬、動作項和條件項。

圖2.15 判定表的結構
(1)條件茬。條件茬部分列出了各種可能的條件。除去某些問題中對各條件的先后次序有特定要求外,通常判定表中條件茬所列條件的先后次序無關緊要。條件項是針對各種條件給出的多組條件取值的組合。
(2)動作茬。動作茬列出了可能采取的動作。這些動作的排列順序并沒有什么約束,但為便于閱讀也可令其按適當的順序排列。
(3)動作項和條件項。動作項和條件項緊密相關,它指出了在條件項各組取值的組合情況下應采取的動作。
任一條件取值組合及其要執行的相應動作稱為規則,它在判定表中是縱向貫穿條件項和動作項的一列。顯然,判定表中列出了多少個條件取值的組合,也就有多少條規則,即條件項與動作項有多少列。
3)判定樹(Decision Tree)
判定樹也是用來表達加工邏輯的一種工具,有時候它比判定表更直觀。用它來描述加工,很容易為用戶接受。下面把前面的檢查發貨單的例子用判定樹表示,如圖2.16所示。

圖2.16 判定樹
在表達一個基本加工邏輯時,結構化語言、判定表和判定樹常常被交叉使用,互相補充。這3種手段各有優缺點。從易學易懂的角度看,判定樹最易學,易懂;結構化語言次之;判定表較難懂。判定表最易進行邏輯驗證,因它考慮了全部可能的情況,邏輯清晰,能夠澄清疑問;結構化語言次之;判定樹較難驗證。判定樹的表達是直觀的圖形表示,一目了然,易于同用戶討論;結構化語言次之;判定表則不夠直觀。作為文檔,結構化語言較好表達;判定表次之;判定樹居后。從可修改的角度看,結構化語言較易修改;判定樹次之;判定表較難修改。
沒有一種統一的方法來構造判定樹,也不可能有統一的方法,因為它是以用結構化語言,甚至是自然語言寫成的敘述文作為構造樹的原始依據的,但還是可以從中找出一些規律。首先,應從文字資料中分清哪些是判定條件,哪些是判定做出的結論。例如,在上面的例子中,判定條件是“金額>$500,欠款≤60 天的發貨單”,要判定的結論是“發出批準書和發貨單”。然后,從資料敘述中的一些連接詞(如除非、然而、但、并且、和、或……)中,找出判定條件的從屬關系、并列關系、選擇關系等。
通過對以上情況的分析,可知對于不太復雜的判定條件,或者使用判定表有困難時,使用判定樹較好。而在一個加工邏輯中,如同時存在順序、判斷和循環時,使用結構化語言較好。而對于復雜的判定,組合條件較多,則使用判定表較好。
總之,加工邏輯說明是結構化分析方法的組成部分,對每個加工都要加以說明。使用的手段,應當以結構化語言為主,對存在判斷問題的加工邏輯,可輔之以判定表和判定樹。
2.3.3 行為建模
行為建模給出需求分析方法的所有操作原則,但只有結構化分析方法的擴充版本才提供這種建模的符號。
1.狀態—遷移圖
利用如圖2.17所示的狀態—遷移圖(STD)或狀態—遷移表來描述系統或對象的狀態,以及導致系統或對象的狀態改變的事件,從而描述系統的行為。
每個狀態代表系統或對象的一種行為模式。狀態—遷移圖指明系統的狀態如何響應外部的信號(事件)進行推移。在狀態—遷移圖中,用圓圈“○”表示可得到的系統狀態,用箭頭“→”表示從一種狀態向另一種狀態遷移。箭頭上要寫明導致遷移的信號或事件的名字。如圖 2.17(a)所示,系統中可取得的狀態=S1、S2、S3,事件=t1、t2、t3、t4。事件t1將引起系統狀態S1向狀態S3遷移,事件t2將引起系統狀態S3向狀態S2遷移,等等。圖2.17(b)是與圖2.17(a)等價的狀態—遷移表。

圖2.17 狀態—遷移圖及與其等價的狀態—遷移表例
另外,狀態—遷移圖指明了作為特定事件的結果(狀態)。在狀態中包含可能執行的行為(活動或加工)。
如果系統比較復雜,可以將狀態—遷移圖分層表示。例如,在確定了圖2.18所示的大狀態S1、S2、S3之后,接下來就可把狀態S1、S2、S3細化,圖2.18對狀態S1進行了細化。此外,在狀態—遷移圖中,由一個狀態和一個事件所決定的下一個狀態可能會有多個。實際會遷移到哪個是由更詳細的內部狀態和更詳細的事件信息來決定的。此時,可采用狀態—遷移圖的一種變形(見圖2.19),使用加進判斷框和處理框的記法。

圖2.18 狀態—遷移圖

圖2.19 狀態—遷移圖的變形
2.Petri網
Petri網(Petri Net Graph,PNG)適用于描述相互獨立、協同操作的處理系統,即并發執行的處理系統。在軟件需求分析與設計階段都可以使用。
Petri網是一種有向圖,它有兩種結點:“○”表示系統的狀態,“—”或“┃”表示系統中的事件。圖中的有向邊表示對事件的輸入,或從事件輸出;“”表示對事件的輸入;“
”表示事件的結果,即從事件的輸出。
圖 2.20 用 Petri 網描述了在一個多任務系統中的兩個進程 PR1 和 PR2使用一個公共資源R時,利用原語LOCK(對資源加鎖)和UNLOCK(對資源解鎖)控制R的使用,保證進程間同步的例子。

圖2.20 進程同步機制的PNG
圖2.20中每個進程是一個數據對象,它有3個狀態:等待資源(p1或p4),占用資源執行的處理(p2或p5),不占用資源執行的處理(p3或p6);另外系統有一個資源空閑(p7)狀態。有的狀態中有一個黑點“”,稱為標記或令牌,它表明系統或對象當前正處于此狀態。當作為一個事件輸入的所有狀態都得到或保有令牌時,才能引起該事件激發,使得系統和對象的狀態向前推移,完成系統和對象的某些行為。
3.控制規格說明
控制規格說明從兩個方面給出系統的行為,一是狀態—遷移圖(STD),它是行為的順序規格說明;二是加工激活表(PAT),它是行為的組合規格說明,表明當事件激發時,數據流程圖中哪些加工要被激活。
加工激活表是在加工的環境中,而不是在狀態的環境中。它包含狀態—遷移圖中的信息,表明當某個事件發生時,控制流圖中的哪些加工要被激活。
控制規格說明僅描述了系統的行為,不提供被激活加工內部工作的細節。