軟件工程之軟件概要設計


在完成對軟件系統的需求分析之后,接下來需要進行的是軟件系統的概要設計。一般說來, 對於較大規模的軟件項目,軟件設計往往被分成兩個階段進行。首先是前期概要設計,用於確 定軟件系統的基本框架;然后是在概要設計基礎上的后期詳細設計,用於確定軟件系統的內部 實現細節。 概要設計也稱總體設計,其基本目標是能夠針對軟件需求分析中提出的一系列軟件問題, 概要地回答問題如何解決。例如,軟件系統將采用什么樣的體系構架、需要創建哪些功能模塊、 模塊之間的關系如何、數據結構如何?軟件系統需要什么樣的網絡環境提供支持、需要采用什 么類型的后台數據庫等。 應該說,軟件概要設計是軟件開發過程中一個非常重要的階段。可以肯定,如果軟件系統 沒有經過認真細致的概要設計,就直接考慮它的算法或直接編寫源程序,這個系統的質量就很 難保證。許多軟件就是因為結構上的問題,使得它經常發生故障,而且很難維護。

 

一、概要設計過程和任務

1.設計過程

概要設計基本過程如圖 5-1 所示,它主要包括三個方面的設計。首先是系統構架設計,用 於定義組成系統的子系統,以及對子系統的控制、子系統之間的通信和數據環境等;然后是軟 件結構和數據結構的設計,用於定義構造子系統的功能模塊、模塊接口、模塊之間的調用與返 回關系,以及數據結構、數據庫結構等。

 概要設計要求建立在需求分析基礎之上,軟件需求文檔是軟件概要設計的前提條件。只有這樣,才能使得開發出來的軟件系統最大限度地滿足用戶的應用需要。 實際上,概要設計的過程也就是將需求分析之中產生的功能模型、數據模型和行為模型等 分析結論進行轉換,由此產生設計結論的過程。在從分析向設計的轉換過程中,概要設計能夠 產生出有關軟件的系統構架、軟件結構和數據結構等設計模型來。這些結論將被寫進概要設計 文檔中,作為后期詳細設計的基本依據,能夠為后面的詳細設計、程序編碼提供技術定位。 需要注意的是,概要設計所能夠獲得的還只是有關軟件系統的抽象表達式,需要專心考慮 的是軟件系統的基本結構,至於軟件系統的內部實現細節如何,則被放到以后詳細設計中去解 決。例如模塊,概要設計中的模塊只是一個外殼,雖然它有確定的功能邊界,並提供了通信的 接口定義,但模塊內部還基本上是空的,諸多具體的功能加工細節則必須等到詳細設計完成以 后才能確定下來。因此,在有關軟件設計的全部工作中,概要設計所提供的並不是最終設計藍 圖,而只是一份具有設計價值的具體實施方案與策略,用於把握系統的整體布局。盡管概要設 計並不涉及系統內部實現細節,但它所產生的實施方案與策略將會最終影響軟件實現的成功與 否,並影響到今后軟件系統維護的難易程度。

 

2.設計任務

概要設計階段的任務既包括技術方面的,也包括管理方面的,具體說來,主要有以下幾個方面:

(1)制定規范

具有一定規模的軟件項目總是需要通過團隊形式實施開發,例如,組成一個或幾個開發小組 來承擔對軟件系統的開發任務。為了適應團隊式開發的需要,在進入軟件開發階段之后,首先應 該為軟件開發團隊制定在設計時應該共同遵守的規范,以便協調與規范團隊內各成員的工作。

 

概要設計時需要制定的規范或標准包括:

      a.需要采用的管理規則,例如操作流程、交流方式、工作紀律等。

      b.設計文檔的編制標准,包括文檔體系、文檔格式、圖表樣式等。

      c.信息編碼形式,硬件、操作系統的接口規約,命名規則等。

      d.設計目標、設計原則。

 

(2)系統構架設計

系統構架設計就是根據系統的需求框架,確定系統的基本結構,以獲得有關系統創建的總 體方案。其主要設計內容包括:

     a.根據系統業務需求,將系統分解成諸多具有獨立任務的子系統。

        b.分析子系統之間的通信,確定子系統的外部接口。

     c.分析系統的應用特點、技術特點以及項目資金情況,確定系統的硬件環境、軟件環境、 網絡環境和數據環境等。

     d.根據系統整體邏輯構造與應用需要,對系統進行整體物理部署與優化。 很顯然,當系統構架被設計完成之后,軟件項目就可按每個具有獨立工作特征的子系統為 單位進行任務分解了,由此可以將一個大的軟件項目分解成許多小的軟件子項目。

 

(3)軟件結構設計

軟件結構設計是在系統構架確定以后,對組成系統的各個子系統的結構設計。例如,將系統進一步分解為諸多功能模塊,並考慮如何通過這些模塊來構造軟件。

軟件結構設計主要內容包括:

    a.確定構造子系統的模塊元素。

    b.根據軟件需求定義每個模塊的功能。

    c.定義模塊接口與設計模塊接口數據結構。

    d.確定模塊之間的調用與返回關系。

    e.評估軟件結構質量,進行結構優化

(4)公共數據結構設計

概要設計中還需要確定那些將被許多模塊共同使用的公共數據的構造。例如,公共變量、 數據文件以及數據庫中數據等,可以將這些數據看作為系統的公共數據環境。 對公共數據的設計包括:

    a.公共數據變量的數據結構與作用范圍。

    b.輸入、輸出文件的結構。

    c.數據庫中的表結構、視圖結構以及數據完整性等。

(5)安全性設計

系統安全性設計包括:操作權限管理設計、操作日志管理設計、文件與數據加密設計以及 特定功能的操作校驗設計等。概要設計需要對以上方面的問題作出專門的說明,並制定出相應 的處理規則。 例如操作權限,假如應用系統需要具有權限分級管理的功能,則概要設計就必須對權限分級管理中所涉及的分級層數、權限范圍、授權步驟以及用戶賬號存儲方式等,從技術角度作出專門的安排。

 

(6)故障處理設計

軟件系統工作過程中難免出現故障,概要設計時需要對各種可能出現的來自於軟件、硬件 以及網絡通信方面的故障作出專門考慮。例如,提供備用設備、設置出錯處理模塊、設置數據備份模塊等。

 

(7)可維護性設計

軟件系統在投入使用以后必將面臨維護,如改正軟件錯誤、擴充軟件功能等。對此,概要設計需要作出專門安排,以方便日后的維護。例如,在軟件中設置用於系統檢測維護的專用模 塊;預計今后需要進行功能擴充的模塊,並對這些接口進行專門定義。

 

(8)編寫文檔

概要設計階段需要編寫的文檔包括:概要設計說明書、數據庫設計說明書、用戶操作手冊。 此外,還應該制定出有關測試的初步計划。 上述文檔中,概要設計說明書是概要設計階段必須產生的基本文檔,涉及系統目標、系統 構架、軟件結構、數據結構、運行控制、出錯處理、安全機制等諸多方面的設計說明。

 

(9)概要設計評審

在諸多概要設計任務完成之后,應當組織對概要設計的評審。 概要設計評審內容主要包括:

    a.需求確認:確認所設計的軟件是否已覆蓋了所有已確定的軟件需求。

    b.接口確認:確認該軟件的內部接口與外部接口是否已經明確定義。

    c.模塊確認:確認所設計的模塊是否滿足高內聚、低耦合的要求,模塊的作用范圍是否在其控制范圍之內。

    d.風險性:該設計在現有技術條件下和預算范圍內是否能按時實現。

    e.實用性:該設計對於需求的解決是否實用。

    f.可維護性:該設計是否考慮了今后的維護。

    g.質量:該設計是否表現出了良好的質量特征

 

二、系統構架設計

大型的綜合應用系統大都是由許多子系統組成的。一般說來,這些子系統能夠獨立運行, 有自己專門的服務任務,並可能需要部署在不同的計算機上工作。 應該說,組成系統的子系統具有一定的獨立性,但子系統之間又有着聯系。例如,有共同的數據源,相互之間需要通信,並可能需要協同工作。系統構架設計的任務就是根據需求規格 中的需求基本框架,把組成系統的這些子系統、子系統之間的關系、它們之間需要的數據通信 等確定下來,並把它們工作時所需要的設備環境、網絡環境和數據環境等也一同確定下來,由 此對系統作出一個合理的、符合應用需要的整體部署。 需求分析中的需求框架是基於用戶應用域建立的,概要設計時可以通過需求框架來映射系 統構架。例如,可以利用需求分析中的高層數據流圖對系統基本工作流程的描述,來映射系統的基本結構,使得需求分析中對系統的邏輯描述,轉換為概要設計中對系統的物理描述。 一般情況下,系統構架設計可以按照以下步驟進行。

(1)定義子系統。根據需求分析中有關系統的業務划分情況,將系統分解成諸多具有獨立任務的子系統。

(2)定義子系統外部接口。分析子系統之間的通信與協作,以獲得對子系統外部接口的 定義。

(3)定義系統物理構架。根據系統的整體邏輯結構、技術特點、應用特點以及系統開發的 資金投入情況等,選擇合適的系統物理構架,包括:硬件設備、軟件環境、網絡結構和數據庫結構,並將子系統按照所選的物理構架進行合理部署與優化。 下面將介紹幾種典型的系統構架。需要注意的是,任何一種結構都會有優點與缺點,盡管 是一些現在看來已經過時的結構也有它存在的現實價值。

 

1.集中式結構

集中式結構是最傳統的系統構架,系統由一台計算機主機和多個終端設備組成,其結構如 圖 5-2 所示。 集中式結構的特點是系統中的全部軟件資源都被集中安裝在這一台主機上,包括:操作系統、數據庫系統、應用系統和資源文件等。系統的智能處理器也被集中在主機上。用戶則是通 過和主機連接的基本無智能的終端設備與系統進行通信。由於所有計算任務都通過主機完成,因此集中式結構對計算機性能有比較高的要求。早期應用中一般使用小型以上計算機提供比較 強大的主機計算支持,操作系統則一般是 Unix 系統,能夠向外提供多用戶服務。

應該說,集中式結構具有非常好的工作穩定性。另外,由於集中式結構是直接通過終端接 口實現多用戶通信,因此系統還具有較高的安全保密特性。集中式結構優點是高穩定性和高安 全性。但集中式結構有較苛刻的設備要求,系統建設費用、運行費用都比較高,而且系統靈活 性不夠好,系統結構不便於擴充。

 

2. 客戶機/服務器結構

客戶機/服務器結構是一種分布與集中相互結合的結構,系統依靠網絡被分布在許多台不同的計算機上,但通過其中的服務器計算機提供集中式服務。 圖 5-3 所示的是客戶機/服務器結構的典型應用。這是一個提供視頻信息和圖片信息的多用戶超文本應用系統,系統中有多個服務器,能夠分別提供不同的信息服務。其中,視頻服務器提供視頻數據服務,傳送的數據需要快速同步,但分辨率相對較低;圖片服務器提供圖片數據服務,數據需要以高分辨率發送;目錄服務器則提供目錄查詢服務,能夠支持各種查詢,並 能夠與超文本信息進行鏈接。 與集中式結構中的無智能終端不同,客戶機/服務器結構中的客戶機是具有智能的,需要 安裝客戶程序,並需要通過客戶程序訪問服務器。例如圖 5-3 中的諸多客戶機,它們可以通過一個用戶界面客戶程序對服務器進行訪問,並可以通過這個用戶界面程序顯示從服務器返回的 圖片或視頻信息。 在客戶機/服務器結構中,客戶機是主動的,它主動地向服務器提出服務請求;而服務器 則是被動的,它被動地接受來自客戶機的請求。一般說來,客戶機在向服務器提出服務請求之 前,需要事先知道服務器的地址與服務;但服務器卻不需要事先知道客戶機的地址,而是根據 客戶機主動提供的地址向客戶機提供相應的服務。

 

客戶機/服務器結構的優越性是結構靈活、便於系統逐步擴充。例如上面的多用戶超文本 應用系統,也許用戶最初只需要提供圖片信息服務,因此系統初期開發時可以只創建圖片服務 器,只是當用戶需要提供視頻信息服務時,才創建視頻服務器。顯然,這有利於應用系統的分 階段實現與逐步擴充。另外,由於客戶機/服務器中服務器可以采用高性能微機配置,因此其建 設成本、運行費用等也明顯低於基於小型機的集中式結構。 需要注意的是,客戶機/服務器結構是一種邏輯結構,客戶機或服務器都只是角色概念。 因此可以將客戶軟件和服務軟件安裝在一台計算機上,而使這台計算機既擔任客戶機角色,又擔任服務器角色。當然,也可以在一台計算機上安裝多個服務軟件,而使這台計算機承擔多個 服務器角色,例如,它可以既是圖片服務器,又是視頻服務器。

 


 3.多層客戶機/服務器結構

客戶機/服務器結構已被廣泛應用基於數據庫的信息服務領域,並演變出了多層客戶機/服 務器結構。 圖 5-4 所示是一個有關信息管理應用的邏輯結構。這是一個三層邏輯結構,其中的表示層 是指對用戶的信息服務;應用層是指對數據的應用邏輯加工; 數據層是指系統中的數據庫管理。在集中式系統中,以上各個不同層面的元素都被部署在一台主機上,這時或許沒有必要在它們之間清楚地划分邊界。但值得注意的是,當采用客戶機/ 服務器結構時,這些元素卻有可能要被分布到不同的計算機上 去,因此必須在它們之間給出一個清楚的邊界。

 

(1)兩層結構

兩層客戶機/服務器結構是將信息表示與應用邏輯處理都 放在了客戶機上,而服務器只需要管理數據庫事務,其結構如 圖 5-5 所示。這時的客戶機一般被稱為“胖客戶機”。

兩層結構的優點是結構簡單,技術上比較容易實現。而且應用軟件基本上是在客戶端工作, 因此非常方便客戶端數據的計算與表現,能夠有 效保證系統的工作性能。 兩層結構的缺陷是在管理與維護上存在困 難。這時的客戶端承擔了信息表示與應用計算雙 重任務,客戶端程序復雜,並且被分散在許多不 同的客戶計算機上。除非應用軟件的功能非常穩 定或客戶端口很少,否則當應用軟件由於用戶應用規則的變化,而不得不對其功能進行改造時, 系統中數目龐大的客戶機群,將會使系統變更顯得非常麻煩,需要很大的系統變更開銷。

 

 

(2)三層結構

三層結構是鑒於兩層客戶機/服務器結構在管理與維護上存在的困難而專門提出的,這就 是使“胖客戶機”減肥,使它盡量簡單,變成“瘦客戶機”。更具體地說,就是將“胖客戶機” 中比較復雜,並且容易發生變化的應用邏輯部分提取出來,將它放到一個專門的“應用服務器” 上,由此產生的結構如圖 5-6 所示。
 

顯然,三層結構使信息表示、應用邏輯處理和數據庫管理被自然地分成了三個獨立的部分。 其中,應用邏輯處理是應用系統中的最易發生需求改變的部分,被放到了應用服務器上。與兩層結構比較,三層結構給系統維護帶來了很大的便利,當用戶應用規則發生變化時,需要改變的不是數目龐大客戶端,而是一個或少數幾個應用服務器。但是,三層結構使實現軟件的技術難度加大、開發周期延長,並且對服務器設備也有更高的要求。 需要指出的是,三層客戶機/服務器結構也是邏輯結構,因此一個單一的服務器計算機可以既是應用服務器,又是數據庫服務器。然而許多情況下,為了使系統具有更高的性能指標, 或使系統具有更好的穩定性,系統中大都分別設置有專門的應用服務器和數據庫服務器。而在一些實際開發中,為了使應用服務器能夠承擔來自於許多客戶機的計算請求,還往往需要根據軟件系統的計算負荷狀態,對應用服務器進行專門的配置設計,例如,按事務進行任務分工, 並在系統中設置多台專門應用服務器,它們分別完成一些特定的服務請求任務。

 

(3)B/S結構

B/S 結構是基於 Web 技術與客戶機/服務器結構的結合而提出來的一種多層結構,其中的 B 是指 Web 瀏覽器(Browse),S 是指應用服務器與數據服務器(Server)。目前,這種結構已被 廣泛應用於網絡商務系統之中,例如網上銀行、網上商店等。其結構圖如圖 5-7 所示。 B/S 結構將信息表示集中到了專門的“Web 服務器”上。因此,與三層客戶機/服務器結構 比較,B/S 結構多了一層服務器。應該說,B/S 結構使客戶端程序更加簡化。這時的客戶機上已 經不需要專門的應用程序了,只要有一個通用的 Web 瀏覽器(例如,Microsoft Internet Explorer),就可以實現客戶端數據的應用。

 

 B/S 結構的優點是不需要對客戶機進行專門的維護(客戶機上沒有專門的應用程序),特別 適合於客戶機位置不固定或需要依靠互聯網進行數據交換的應用系統。缺點是最終用戶信息需 要通過 Web 服務器獲取,並通過網絡傳送到客戶機上,因此系統的數據傳輸速度以及系統的穩定性,都將明顯低於三層客戶機/服務器結構。 如同其他客戶機/服務器結構一樣,B/S 結構也是邏輯結構,因此一個單一的服務器計算機 可以既是 Web 服務器,又是應用服務器和數據庫服務器。但如果需要使系統具有更高的性能或 更加穩定的運行狀態,那么則有必要將 Web 服務、應用處理和數據管理從物理上分離開來,設 置專門的 Web 服務器計算機、應用服務器計算機和數據庫服務器計算機。 在許多應用中,B/S 結構和三層客戶機/服務器往往被結合起來使用。例如“網上購物系統”, 其面向消費者的購物操作一般采用的是 B/S 結構,但面向購物中心工作人員的相關操作,為了 保證系統運行穩定快捷,則可能會采用三層客戶機/服務器結構。其對應的物理構架如圖 5-8      所示。

B/S 結構的優點是不需要對客戶機進行專門的維護(客戶機上沒有專門的應用程序),特別 適合於客戶機位置不固定或需要依靠互聯網進行數據交換的應用系統。缺點是最終用戶信息需 要通過 Web 服務器獲取,並通過網絡傳送到客戶機上,因此系統的數據傳輸速度以及系統的穩 定性,都將明顯低於三層客戶機/服務器結構。 如同其他客戶機/服務器結構一樣,B/S 結構也是邏輯結構,因此一個單一的服務器計算機 可以既是 Web 服務器,又是應用服務器和數據庫服務器。但如果需要使系統具有更高的性能或 更加穩定的運行狀態,那么則有必要將 Web 服務、應用處理和數據管理從物理上分離開來,設 置專門的 Web 服務器計算機、應用服務器計算機和數據庫服務器計算機。 在許多應用中,B/S 結構和三層客戶機/服務器往往被結合起來使用。例如“網上購物系統”, 其面向消費者的購物操作一般采用的是 B/S 結構,但面向購物中心工作人員的相關操作,為了 保證系統運行穩定快捷,則可能會采用三層客戶機/服務器結構。其對應的物理構架如圖 5-8 所示。

 

(4)組件對象分布式結構

組件是一個對象包。組件對象分布式結構就是通過組件而使軟件系統中的組件對象被分布到網絡上的多台計算機上。組件對象具有一些公共接口,能夠向外提供服務,不同組件的對象 之間可以通過公共接口相互通信和協同工作。 應該說,傳統的客戶機/服務器結構是一種不對稱的分布式結構,其客戶機和服務器具有不同的地位。客戶機能夠接受來自服務器的服務,但不能接受其他客戶機的服務;服務器能夠 扮演客戶機的角色,由此接受來自其他服務器的服務,但它不能請求來自客戶機的服務。 然而,組件對象分布式結構則是一種比較對稱的結構,在這種結構中,已經沒有了客戶機與服務器之間的界限,這些對象既可充當服務器,也可充當客戶機,其角色只是決定於它是在 提供服務還是在請求服務。

組件對象分布式結構是基於對象中間件建立的。主要用於對象分布式計算的中間件有:

•  CORBA(通用對象請求代理模型):由對象管理組織(OMG)定義,提供了一組通用的與 機器無關的分布式對象計算方法。可用在 Unix、Linux 或 Windows 上。

•    DCOM(分布式組件對象模型):由微軟公司定義,主要用在微軟公司的操作系統上。  可以把對象中間件看成是能夠在其上插拔組件的軟件總線。這就像硬件總線允許不同的接 口卡插於其上以支持硬件設備之間的通信一樣,對象中間件作為軟件總線,也允許在其上添加 或移走組件對象,或進行組件對象之間的相互通信。其邏輯結構如圖 5-9 所示。

 

應該說,組件對象分布式結構是一個開放的體系構造,它不僅允許新的組件對象根據需要 增加進來,而且還允許使用不同語言編寫的對象。現在,組件對象分布式結構已經成為構造軟 件系統的一種基本模式,諸多運行在互聯網上的遠程服務系統,它們即是按照這種結構構造的。
 在應用系統中采用組件對象分布式結構時,可依照以下步驟來進行系統結構設計:

(1)按照系統功能服務對系統進行邏輯分塊,確定系統的邏輯構造。

(2)以系統邏輯構造為依據,設計系統的分布式組件對象。

(3)以組件之間的通信與協作為依據,對組件進行物理部署。

組件對象分布式結構具有靈活的構架,系統伸縮性好,能夠給系統的功能調整與擴充帶來 便利。但是,采用完全分布的組件對象結構,其技術難度太大,內部結構也較復雜。相比之下, 客戶機/服務器結構是一種更加容易理解的結構,並與現實的組織機構、業務過程具有一致性。 因此,在許多實際應用中,往往將組件對象分布式結構與客戶機/服務器結構結合起來,其中組 件對象分布式結構被作為一種實現技術嵌入到客戶機/服務器系統之中。這種構架的特點是:系 統先按照客戶機/服務器結構進行邏輯構造;然后無論是客戶機還是服務器,都按照組件對象分 布式結構進行內部構造設計,它們都由組件組成,並都需要通過對象中間件實現通信。顯然, 這樣的系統將更加具有柔性,系統的變更也將會變得更加容易。例如,一個二層客戶機/服務器 結構,只需要對其組件對象進行重新部署,就可以將其改造成為三層甚至多層客戶機/服務器   結構。 實際上,分布式組件對象技術能夠給應用服務器的創建帶來更好的可伸縮性,由諸多組件構造的應用服務器可以更加自由地進行物理部署。例如一個供銷管理系統,假設其包括供應商 聯系、庫存控制、客戶聯系、貨物訂購等業務內容,並且這些業務都由一個供銷部門負責,則 系統構造可按以上業務創建組件,並將這些組件部署在一台應用服務器上,如圖 5-10 所示。

 

但假如業務流程發生了變化,例如,由於業務量擴大,該供銷部門需要拆分為供應部、銷售部兩個部門時,考慮到業務歸口與服務器負荷的影響,上面的一台應用服務器也需要改變為兩台應用服務器,分別承擔供應與銷售的事務處理。顯然,系統所采用的組件對象分布式結構 能夠很方便地適應這種業務需求的變更,需要進行的系統改造只不過是將用於業務處理的組件 重新進行部署或安裝,如圖 5-11 所示。

 

三、軟件結構設計

軟件結構設計是對組成系統的各個子系統的進一步分解與規划。例如,將子系統按照其功 能要素分解成具有一定的功能邊界的模塊,然后以模塊為單位來構造軟件。顯然,需求分析階 段已經建立起的有關系統的功能模型、數據模型或狀態機模型,可以作為軟件結構設計的前提 依據。 具體說來,軟件結構設計包括以下幾方面的內容:

(1)確定構造子系統的模塊元素。

(2)定義每個模塊的功能。

(3)定義模塊接口,設計接口的數據結構。

(4)確定模塊之間的調用與返回關系。

(5)評估軟件結構質量,進行結構優化。

 

1.模塊概念

(1)模塊化

模塊概念產生於結構化程序設計思想,這時的模塊被作為構造程序的基本單元,例如函數、 過程。 在結構化方法中,模塊是一個功能單位,因此模塊可大可小。它可以被理解為所建軟件系 統中的一個子程序系統,也可以是子程序系統內一個涉及多項任務的功能程序塊,並可以是功 能程序塊內的一個程序單元,例如函數、過程。也就是說,模塊實際上體現出了系統所具有的 功能層次結構。 模塊可以使軟件系統按照其功能組成進行分解,而通過對軟件系統進行分解,則可以使一 些大的復雜的軟件問題分解成諸多小的簡單的軟件問題。從軟件開發的角度來看,這必然有利 於軟件問題的有效解決。對於這個結論,可以進行以下論證: 現假設函數 C ( P )用於度量問題 P 的復雜程度,函數 E ( P )用於度量為解決問題 P 所需 要的工作量(用時間計算)。並假設有兩個問題 P 1和 P 2。 如果有: C ( P 1)> C ( P 2) 則必有: E ( P 1)> E ( P 2) 這是一個顯而易見的經驗性結論。它表明:問題越復雜,解決這個問題所需要的工作量就 越大,需要花費時間就越多。 另一個來源於經驗的結論是: C ( P 1 + P 2)> C ( P 1)+ C ( P 2) 它表明:如果能夠把兩個結合在一起的問題隔離開來單獨解決,則可以使這原本結合在一 起的問題的復雜程度下降。 顯然,從上面兩個經驗性結論中可以作出以下推論: E ( P 1 + P 2)> E ( P 1)+ E ( P 2) 它表明:如果能夠把兩個結合在一起的問題隔離開來單獨解決,則可以使這原本難於解決 的問題變得容易解決起來。這個結論就是模塊化的基本依據,其作用就是能夠使大的復雜的問 題被“各個擊破”。 上述結論表明:模塊化可以使軟件問題簡化。但是,得出這個結論需要有下面的前提條件: 大模塊被分解成諸多小模塊之后,小模塊基本上處於相互隔離的獨立狀態,它們之間沒有太多 的通信。否則,小模塊之間由於存在太多的通信,將會導致小模塊接口復雜起來,其結果是, 雖然每個模塊內部簡化了,但整個軟件問題反而復雜起來。 許多人都有一個良好的願望,那就是依靠模塊化使系統不斷分解而使整個系統不斷簡化, 由此使軟件開發成本不斷下降。然而這卻可能做不到,因為隨着系統的分解,系統中模塊數目 將會增加,模塊接口也會增加,軟件構造會由此變得復雜起來,模塊連接的難度也會由此加大。實際上還有一個因素也在阻礙着這個願望的實現,這就是軟件系統的模塊化分解本身也是一件 並不輕松的工作,假如分解系統所需要的工作量,已經超過因為模塊簡化而減少的工作量,那 就意味着,進一步分解系統已是一件得不償失的事情了。 因此,軟件系統模塊化分解,從軟件成本角度來看,有一個最小成本模塊數范圍。如圖 5-12 所示,若分解程度低於這個最小成本模塊數范圍,則可繼續分解,以降低軟件開發成本;但若 分解程度已經達到這個最小成本模塊數范圍,則就沒有必要再進行分解了,否則將會反而增加 軟件開發的成本。
 

 

(2)抽象化

抽象是人所具有的一種高級思維活動,是以概括的方式抽取一系列事物的共同特征,由此 把握事物的本質屬性。抽象也是人類解決復雜問題時強有力的手段,能夠使人從事物復雜的外 部表象中發現事物的內在本質規律,由此找到解決問題的有效途徑。 這種抽象的方法也被運用於軟件工程之中。實際上,軟件工程的每一個階段,都能夠看到 抽象思維方法的作用,從軟件的定義到軟件的設計,直到軟件編碼與最終實現。但是,在軟件工程的不同階段,抽象層次與對象卻各不相同,並需要運用不同的語言進行描述。例如,在軟件分析階段,抽象對象是系統的外部特征,需要采用的描述語言是軟件問題所處環境中的用戶 術語;而在設計階段,抽象對象則是系統的內部構造,需要采用的描述語言則是更加規范的適 合於系統構造的過程化語言。 概要設計中的功能模塊往往被看成是一個抽象 化的功能黑盒子,其特征如圖 5-13 所示。雖然它已 是一個與軟件實現直接相關的實體單元,可以看到 它清晰的外觀,但是卻看不到它內部更加具體的實 現細節。 抽象的作用是對事物現象的高度概括,但抽象 的最終目的則是走到它的對立面,產生出具體的結 果。因此,一個完整的抽象化過程是既包含抽象又 包含具體的循環演變過程。應該說,正是由抽象到具體的不斷演變,才使得人的抽象認識能夠不斷地產生出有意義的結果,並不斷地推動着人類 思想的進步。 這種由抽象到具體的不斷演變也一直貫穿於軟件工程過程之中,這就是自頂向下、逐步細 化,其中,頂是抽象的,而細化則是這個抽象的頂具體化的結果。這意味着,軟件工程的每一 個階段的推進,都具有從抽象到具體的轉化。 例如需求分析,它建立在可行性研究基礎之上。可行性研究所獲得的是有關整個計算機系 統的外部模型,這是一種對整個系統的高度抽象。但是,隨着需求分析的進行,可行性研究中 高度抽象的系統模型被逐步地轉變成需求分析模型中每一個功能局部的規格定義。顯然,這是 軟件從高層定義到低層定義的具體化演變。 又如概要設計,它是在需求分析基礎上進行的,需要根據需求分析中的基本要求設計軟件 系統的基本構架,需要按照需求分析所提出的功能規格,確定軟件系統中模塊的構成,定義模 塊的接口,確定模塊之間通信,設計對模塊的控制。顯然,這是軟件從系統定義到系統設計的 具體化演變。 應該說,概要設計中的結論,對於軟件內部構造而言則仍是抽象的。比如概要設計中的功 能模塊,盡管它有惟一的名稱標識,有明確的功能定義,並設置有數據的輸入輸出接口。但是, 模塊的內部實現細節則處於待定狀態,需要等到詳細設計完成以后才能得出更加具體的算法結論。

 

(3)信息隱藏

設計軟件結構時一個不可回避的問題是:為了得到一種高質量的模塊組合,應該如何分解 軟件。對此,不得不了解什么是“信息隱蔽”。 信息隱蔽是指每個模塊的內部實現細節對於其他模塊來說是隱蔽的。也就是說,模塊中所 包含的信息,例如,模塊內部的數據、語句或過程等,不允許其他不需要這些信息的模塊使用。 顯然,信息隱蔽有利於模塊相互之間的隔離,可以使每個模塊更加具有獨立性,並可以使模塊 之間的通信受到限制。例如,模塊之間只能傳遞那些對於其功能實現而言是必須的信息。 通過限制模塊需要使用的數據的作用范圍,例如,定義模塊內部局部變量,可以產生出模塊內部信息隱蔽的效果。 模塊內部信息隱蔽的好處是可以使軟件系統更加健壯,更加方便維護。 以模塊中的錯誤為例,假如模塊內部信息是隱蔽的,則模塊中存在的這個錯誤將比較難於擴散到其他模塊。否則,系統可能因為一個小錯誤的擴散,而使整個系統崩潰。實際上,信息 隱蔽還使軟件錯誤定位更加方便。由於軟件出錯位置容易發現,因此,整個軟件糾錯工作的效 率、質量都會隨之提高。 一些模塊的功能有時需要根據用戶需求的變更而適時地進行一些功能改造。當需要對模塊 進行功能改造時,模塊內部的信息隱蔽會使對模塊改造所帶來的影響限制在需要改造的模塊之 內,而與其他模塊無關。顯然,這將使軟件系統的局部修改變得更加便利。

 

2.模塊的獨立性

模塊的獨立性是指軟件系統中每個模塊都只涉及自己特定的子功能,並且模塊接口簡單, 與軟件中其他模塊沒有過多的聯系。

模塊獨立性是衡量軟件中模塊質量最重要的指標,是設計與優化軟件結構時必須考慮的重要因素。當軟件中的每個模塊都具有很好的獨立性時,軟件系統不僅更加容易實現,並且會使今后的維護更加方便。 模塊的獨立性一般采用耦合和內聚這兩個定性的技術指標進行度量。其中,耦合用來反映 模塊之間互相連接的緊密程度,模塊之間的連接越緊密,聯系越多,耦合性就越高。內聚用來反映模塊內部各個元素彼此結合的緊密程度,一個模塊內部各個元素之間結合越緊密,則它的 內聚性就越高。顯然,為了使模塊具有較強的獨立性,要求模塊是高內聚、低耦合。

(1)耦合

耦合是軟件結構中各個模塊之間相互關聯程度的度量。耦合的強弱取決於各個模塊之間接 口的復雜程度、接口數據對模塊內部計算的影響程度和調用模塊的方式。 模塊之間的耦合形式主要有:非直接耦合、數據耦合、控制耦合、公共耦合和內容耦合。 其中,非直接耦合和數據耦合是較弱的耦合,控制耦合和公共耦合是中等程度的耦合,內容耦 合則是強耦合。 模塊化設計的目標是盡量建立模塊間耦合松散的系統。因此,在設計軟件結構時一般也就 要求盡量采用非直接耦合和數據耦合,少用或限制使用控制耦合和公共耦合,絕對不能使用內 容耦合。 為了更好地認識模塊之間的耦合,下面將對上述各種耦合形式給出必要說明。

a.非直接耦合

如果兩個模塊之間沒有直接關系,它們之間的聯系僅限於受到共同主模塊的控制與調用, 則稱這種耦合為非直接耦合。 由於非直接耦合的模塊之間沒有數據通信,因此模塊的獨立性最強。

b.數據耦合

當一個模塊訪問另一個模塊時,如果彼此之間是通過模塊接口處的參數實現通信,並且參 數所傳遞的數據僅用於計算,而不會影響傳入參數模塊的內部程序執行路徑,則稱這種耦合為 數據耦合。 數據耦合是一種松散的耦合。依靠這種類 型的耦合,模塊之間既能實現通信,又有比較 強的獨立性。因此,軟件結構設計中提倡使用 這類耦合

c.控制耦合

當一個模塊訪問另一個模塊時,如果彼此 之間是通過模塊接口處的參數實現通信,並且 參數傳遞了開關、標志、名字等控制信息,由 此影響了傳入參數模塊的內部程序執行路徑, 則稱這種耦合為控制耦合如圖 5-14 所示。 由於接口參數影響着內部程序執行路徑, 因此控制耦合比數據耦合要強一些,會使模塊 的獨立性有所下降。當需要通過一個單一的接口傳遞模塊內多項功能的選擇信息時,往往需要用到控制耦合。顯然,在控制耦合形式下,對 所控制模塊的修改,需要受到控制參數的限制。

d.公共耦合 公共耦合是一種通過訪問公共數據環境而實現通信的模塊耦合形式,例如,獨立於模塊而 存在的數據文件、數據表集、公共變量等,都可以看作為公共數據環境。 公共耦合中的公共數據環境是提供給任何模塊的,當模塊之間的耦合是公共耦合時,那些 原本可以依靠接口提供的對數據的限制也就沒有了。因此,相比依靠接口的耦合形式,公共耦 合必然會使模塊的獨立性下降。也正因為如此,實際應用中,只有在模塊之間需要共享數據, 並且通過接口參數傳遞不方便時,才使用公共耦合。 需要注意的是:模塊之間公共耦合的復雜程度,將會隨着耦合模塊個數的增加而顯著增加。 為了降低公共耦合帶來的復雜性和提高模塊的獨立性,實際應用中還會針對公共耦合專門設置 一些限制,例如不使用公共耦合數據傳遞控制信息。 圖 5-15 中的模塊采用了訪問公共數據環境的公共耦合形式。其中圖(a)是一個模塊只往 公共數據環境里送進數據,另一個模塊只從公共數據環境中取出數據,這是一種比較松散的公 共耦合;而圖(b)則是兩個模塊都可以向公共數據環境里送進數據,又都可以從公共數據環境 中取出數據,這就是一種比較緊密的公共耦合。
 

另外,公共耦合還會帶來以下一些方面的影響: •  由於所有公共耦合模塊都會與某一個公共數據環境有關,因此修改公共數據環境中某個 數據的結構,將會影響到所有被耦合的模塊。

•  由於沒有辦法控制各個模塊對公共數據的存取,因此公共耦合會影響軟件模塊的可靠性 和適應性。

•  由於公共數據環境需要被許多模塊使用,因此不得不使用具有公共意義的數據名稱。顯 然,這會使得程序的可讀性有所下降。

e.內容耦合 如果發生下列情形,兩個模塊之間就發生了內容耦合。

•  一個模塊直接訪問另一個模塊的內部數據。

•  一個模塊不通過正常入口轉到另一模塊內部。 •  兩個模塊有一部分程序代碼重疊。

•  一個模塊有多個入口。 內容耦合是一種非常強的耦合形式,嚴重影響了模塊獨立性。當模塊之間存在內容耦合時,模塊的任何改動都將變得非常困難,一旦程序有錯則很難修正。因此,設計軟件結構時,也就 要求絕對不要出現內容耦合。所幸的是,大多數高級程序設計語言已經設計成不允許出現內容 耦合,它一般只會出現在匯編語言程序中。

 

(2)內聚

內聚是對模塊內部各個元素彼此結合的緊密程度的度量。模塊內部各個元素之間的聯系越緊密,則它的內聚程度就越高。模塊的設計目標是盡量使模塊的內聚程度高,以達到模塊獨立、 功能集中的目的。 模塊內聚的主要類型有:功能內聚、信息內聚、通信內聚、過程內聚、時間內聚、邏輯內 聚和偶然內聚,如圖 5-16 所示。其中,功能內聚和信息內聚屬於高內聚,通信內聚和過程內聚 屬於中等程度的內聚,時間內聚、邏輯內聚和偶然內聚則屬於低內聚;而且,模塊內聚程度越 高,其功能越集中、獨立性越強。
 

內聚所體現的是模塊的內部功能構造,耦合所體現的是模塊之間的聯系。一般情況下,內 聚和耦合是相互關聯的,模塊的內聚程度越高,則模塊間的耦合程度就會越低,但這也不是絕 對的。值得指出的是,比起模塊之間的耦合來,模塊的內聚更顯重要。因此,實際設計中應當 把更多的注意力放在如何提高模塊的內聚程度上。 模塊內聚的提高依賴於對模塊功能的正確認識,應該通過定義使每一個模塊都具有明確的 功能。為了更好地認識模塊內聚,下面將對上述幾種內聚類型分別加以說明。

a.偶然內聚

當模塊內各部分之間沒有聯系,或即使有聯系,這種聯系也很松散時,將會出現偶然內聚。偶然內聚往往產生於對程序的錯誤認識或沒有進行軟件結構設計就直接編程。例如,一些 編程人員可能會將一些沒有實質聯系,但在程序中重復多次出現的語句抽出來,組成一個新的 模塊,這樣的模塊就是偶然內聚模塊。 偶然內聚模塊由於是隨意拼湊而成,模塊內聚程度最低、功能模糊,很難進行維護。

b.邏輯內聚

邏輯內聚是把幾種相關的功能組合在一起形成為一個模塊。在調用邏輯內聚模塊時,可以 由傳送給模塊的判定參數來確定該模塊應執行哪一種功能。例如圖 5-17 中的打印模塊。 邏輯內聚模塊比偶然內聚模塊的內聚程度要高,因為它表明了各部分之間在功能上的相關 關系。但是它每次執行的不是一種功能,而是若干功能中的一種,因此它不易修改。另外,在 調用邏輯內聚模塊時,需要進行控制參數的傳遞,由此增加了模塊間的耦合。

 

c.時間內聚

時間內聚模塊一般是多功能模塊,其特點是模塊中的各項功能的執行與時間有關,通常要 求所有功能必須在同一時間段內執行。例如初始化模塊,其功能可能包括給變量賦初值、連接 數據源、打開數據表、打開文件等,這些操作要求在程序開始執行的最初一段時間內全部完成。
 時間內聚模塊比邏輯內聚模塊的內聚程度又稍高一些,其內部邏輯比較簡單,一般不需要 進行判定轉移。

d.過程內聚

如果一個模塊內的處理是相關的,而且必須以特定次序執行,則稱之為過程內聚模塊。在 使用流程圖設計程序的時侯,常常通過流程圖來確定模塊划分,由此得到的就往往是過程內聚 模塊。例如,可以根據流程圖中的循環部分、判定部分和計算部分將程序分成三個模塊,這三 個模塊就是過程內聚模塊。 過程內聚模塊的內聚程度比時間內聚模塊的內聚程度更強一些,但過程內聚模塊僅包括完 整功能的一部分,因此模塊之間的耦合程度比較高。

e.通信內聚

如果一個模塊內各功能部分都使用了相同的輸入數據或產生了相同的輸出數據,則稱之為 通信內聚模塊。例如圖 5-18 中的處理工資模塊。 通信內聚模塊由一些獨立的功能組成,因此其內聚程度比過程內聚程度要高。

f.順序內聚

如果一個模塊內的諸多功能元素都和某一個功能元素密切相關,而且這些功能元素必須順 序安排(前一項功能的數據輸出作為后一項功能的數據輸入),則稱之為順序內聚模塊。當根據 數據流圖划分模塊時,由此得到的通常就是順序內聚模塊。例如圖 5-19 中的入庫統計模塊。 順序內聚模塊也包含着多項功能,但它有一個核心功能,其他功能則圍繞着這個核心而安 排。因此,順序內聚程度比通信內聚程度更高。
 

g.功能內聚

如果一個模塊中各個部分都是完成某一具體功能必不可少的組成部分,各個部分協同工 作、緊密聯系、不可分割,則稱該模塊為功能內聚模塊。 功能內聚模塊的特征是功能單一、接口簡單,因此其容易實現、便於維護。與其他內聚類 型相比,功能內聚具有最高的內聚程度,軟件結構設計時應以其作為追求目標。


 3.結構化設計建模

軟件結構設計涉及模塊功能、模塊接口與模塊調用關系等問題,為了使這些問題能夠集中 清晰地表達出來,軟件結構設計需要借助於一定的圖形工具來建立設計模型,例如軟件結構圖、 HIPO 圖。

(1)軟件結構圖

軟件結構圖由 Yourdon 於 20 世紀 70 年代提出,並被廣泛應用於軟件結構設計中,能夠有 效說明軟件中模塊之間的調用與通信。 軟件結構圖使用矩形框表示模塊(框內注明模塊的名字或主要功能),使用帶箭頭的直線 段連接上下級模塊,以表示上級模塊對下級模塊的調用。此外,軟件結構圖還可以在調用箭頭 旁使用帶注釋的箭頭,以表示上級模塊在調用下級模塊時參數的傳遞與結果的返回,其基本圖 形符號如表 5-1 所列。

圖 5-20 是一個自動閱卷系統的軟件結構圖。閱卷總控模塊為頂層模塊,其調用考卷數據 輸入、閱卷處理和考卷成績輸出這三個模塊,以進行考卷輸入、成績計算和成績輸出的控制。 在更下一級模塊調用中,考卷數據輸入模塊通過調用讀答卷卡模塊將考卷原始數據輸入,然后 調用檢驗考卷數據模塊產生出適合評分計算的有效數據;考卷成績輸出模塊則通過調用格式化 成績數據模塊對計算出的成績數據進行輸出前的格式化處理,然后調用寫成績記錄模塊實現成 績的存檔操作。
 

(2)HIPO 圖

HIPO 圖是美國 IBM 公司推出的“H 圖”與“IPO 圖”的組合。

  a.H 圖

H 圖是軟件層次圖的簡稱,用於描述軟件結構上的分層調用關系,作用類似於軟件結構圖, 但不涉及調用時的數據流、控制流等附加信息。 H 圖的優點是清晰度高,能夠用於正式文檔中對軟件結構的描述。圖 5-21 是自動閱卷系統 的 H 圖,可以看出,它比上面的軟件結構圖要清晰得多。 為了能使 H 圖中的模塊具有可追蹤性,由此可以與它所對應的 IPO 圖聯系起來。圖中模塊 除了最頂層的之外,其他的模塊都需要按照一定的規則編號,以方便檢索。

  b.IPO圖

IPO 圖是“輸入—處理—輸出圖”的簡稱,其中的“I”是指輸入,“O”是指輸出,“P” 是指處理。可以使用 IPO 圖對模塊進行外部特征描述,涉及輸入、輸出接口和基本加工步驟等。 在 HIPO 圖中,需要針對 H 圖中的每個模塊給出 IPO 圖描述。

從上面的 IPO 圖舉例可以看到,IPO 圖提供了有關模塊的更加完整的定義和說明。顯然, 這將有利於由概要設計到詳細設計的過渡。

 

4.軟件結構優化

軟件結構設計往往需要經歷多次反復,其作用是可以不斷地改進軟件結構,提高軟件質量。 為了改進軟件結構,軟件設計人員進行了長期的實踐與總結,由此得到了一些優化設計的原則。 本節將介紹這些原則。

(1)使模塊功能完整

一個完整的功能模塊,不僅能夠完成指定的功能,而且還應當能夠將完成任務的狀態通知 使用者。 具體說來,一個完整的功能模塊應當包含以下幾個部分的內容:

  a.執行規定功能的部分。

  b.出錯處理的部分。當模塊不能完成規定的功能時,必須回送出錯標志,並向它的調用 者報告出現這種例外情況的原因。

  c.如果需要返回一系列數據給它的調用者,在完成數據加工時,應當給它的調用者返回 一個該模塊執行是否正確結束的“標志”。

(2)使模塊大小適中

許多情況下,可以用模塊中所含語句的數量的多少來衡量模塊的大小。有人認為限制模塊 的大小也是減少模塊復雜性的有效手段之一,因而要求把模塊的大小限制在一定的范圍之內, 例如將模塊內的語句限制在 50~100 行左右。當然,這只能作為參考。 一般說來,模塊過大的原因往往是模塊的功能太多,因此有必要對大模塊做進一步的分解。 大多數情況下,可以從大模塊中分解出一些下級模塊或同層模塊。 軟件結構設計時,也有可能出現模塊過小的問題。如果模塊太小,則要注意這個模塊的功 能是否完整,是否將一個完整的功能分解到多個模塊中去了。許多情況下,可以考慮將較小的 模塊與調用它的上級模塊合並。如果模塊雖小但功能內聚性好,或者它為多個模塊所共享,或 者調用它的上級模塊很復雜,則不要貿然將小模塊與其他模塊合並,而是需要做更加細致的分析。

(3)使模塊功能可預測

一個功能可預測的模塊可以被看成是一個“黑箱”,無論內部處理細節如何,只要輸入數 據是相同的,就總能產生相同的輸出結果。 例如,在模塊中使用了靜態變量。因為靜態變量會在模塊內部產生較難預見的存儲,而如 果這個靜態變量又被用為多項功能的選擇標記,則可能會使得模塊的功能難以被調用者預知。 由於這個原因,設計者要特別慎重地使用靜態變量。 模塊功能可預測還意味着,模塊的功能必須明確清晰地定義,應該使模塊具有很好的內   聚性。

(4)盡量降低模塊接口的復雜程度

模塊接口是模塊與外界進行通信的通道,較復雜的接口往往會帶來較高的耦合。因此,應 努力降低模塊接口的復雜程度。對此,可以從以下兩個方面作出考慮。

a.接口參數盡量采用簡單數據類型,以使接口容易理解。例如,盡量使用基本字符、整 數類型,而不是數組、指針、結合體類型。

b.限制接口參數的個數。接口參數個數太多,往往是由於模塊功能混雜,不得不依靠參 數進行調控。因此,過多的參數往往意味着模塊還有進一步分解的必要。

(5)使模塊作用范圍限制在其控制范圍之內

模塊的控制范圍包括它本身及其所有從屬於它的直接或間接下級模塊。如圖 5-24 所示, 模塊 B 的控制范圍是模塊 E、F、G、K,模塊 C 的控制范圍是模塊 H、I、L、K,模塊 D 的控制范 圍是模塊 I、J、L。 模塊的作用范圍則是指模塊內一個判定的影響范圍,凡是受這個判定影響的所有模塊都屬 於這個判定的作用范圍。其中,如果一個判定的作用范圍包含在這個判定所在模塊的控制范圍 之內,則這種結構是簡單的;否則,其結構就是不簡單的,需要進行結構調整。 例如,圖 5-24 中的模塊 F。如果它做出一個判定之后,接着需要模塊 G 工作,由於模塊 G 不在模塊 F 控制范圍之內,因此模塊 F 必須返回一個信號給模塊 B,再由 B 把信號傳送給模塊 G。 顯然這不是一個好的設計,它增加了模塊之間數據的傳送量,並使模塊之間出現了控制耦合, 因此需要對其結構進行調整。
 

在設計過程中,如果發現模塊的作用范圍不在控制范圍之內時,可以采用如下辦法進行結 構調整,把模塊的作用范圍移到其控制范圍之內。

(1)將判定所在的模塊合並到它的父模塊中去,或上移到層次較高的位置上去,由此可使 判定處於一個較高的位置,以達到有效的控制。例如,將模塊 F 與模塊 B 合並,如圖 5-25 所示, 由此可使模塊 G 受到控制。

(2)將受判定影響的模塊下移到控制范圍以內。例如,將模塊 G 下移到模塊 F 之下,如圖 5-26 所示,由此可使模塊 G 受到模塊 F 控制。 需要注意的是:在改進模塊的結構時,應當根據具體情況通盤考慮,既要盡量小范圍地調 整結構,使改進后的軟件結構能夠最好地體現問題的原來結構,又要考慮改進后的結構在實現 上的可行性。

 

(6)深度、寬度、扇出和扇入應當適當

軟件的深度是指軟件結構的層數。例如,圖 5-24 中的軟件結構,其深度為 4 層。

軟件的寬度是指軟件結構同一個層次上模塊的總個數的最大值。例如,圖 5-24 中的軟件 結構,其第二層寬度是 3,第三層寬度是 6,第四層寬度是 2。其整個軟件的寬度是 6。 軟件結構上的深度、寬度,在一定程度上反映出了軟件系統的規模和復雜程度。也就是說, 軟件規模越大越復雜,其深度、寬度也會越大。一般說來,深度、寬度會受模塊的扇出、扇入 影響,並應該有一個合適的大小。深度、寬度太小,往往表示模塊分解得還不夠細,需要進一 步分解。而深度、寬度太大,則可能表示模塊分解得太細小了,或功能冗余模塊太多了,以致 軟件結構變得復雜起來。一般說來,軟件結構越復雜,模塊之間的耦合就會越大。因此,假如 軟件結構過於復雜,就有必要將一些模塊進行適當的合並,將那些功能相同或相似的模塊合並 起來作為公共模塊使用。 模塊的扇出是指模塊直接調用的下級模塊的個數。比較適當的扇出數為 2~5,一般不要超 過 9。如果一個模塊的扇出過大,就表明該模塊具有過分復雜的控制功能,需要協調和控制過 多的下屬模塊。對此,應當適當增加中間層次的控制模塊,將比較集中的控制分解開來,如圖 5-27 所示。但扇出過小也不好,這樣將使得軟件結構的深度大大增加,會帶來過多的調用和返 回的時間開銷,由此降低軟件的工作效率。

模塊的扇入是指模塊受到了多少個直接上級模塊的調用。一個模塊的扇入越大,則共享該 模塊的上級模塊的數目就越多。如果一個模塊的扇入數太大,而它又不是公用模塊,則說明該 模塊可能具有多項功能。在這種情況下,應當對它做進一步的分析,並將其功能做進一步的分解。

一般說來,各個不同層次的模塊具有以下特點:頂層模塊起全局控制作用;中間層次的模 塊起局部控制作用,並適當承擔一些簡單的操作提示功能;底層模塊擔任具體加工任務。因此, 一個設計得比較好的軟件結構通常應具有這樣的特征:頂層模塊高扇出,中層模塊低扇出,底 層模塊高扇入。

 

四、面向數據流的結構設計

作為構造軟件的基本框架,軟件結構應該與需要分析時建立的分析模型保持一致。一種非 常有效的設計思路是,基於需求分析中的數據流模型進行軟件結構映射,由此產生出軟件系統 的基本設計模型。 為了方便從數據流模型中映射出軟件結構來,需要對數據流進行合理的分類。例如,將數 據流分為變換流或事務流,然后按照它們各自不同的特點分別采取不同的映射方法。

1.變換流分析與設計

(1)變換流

變換數據流所體現出的是數據從輸入到加工再到輸出的一般步驟。變換數據流對數據的加 工流程如圖 5-28 所示,這就是數據首先需要經過輸入過程,將外部數據形態轉變為適合進行加 工處理的內部形態;然后經過變換中心,將已轉成內部形態的輸入數據加工成一種新的數據形 態;接着再經過輸出過程,將經過加工產生的新的數據結果轉換成適合向外導出的數據形態。

(2)高層框架

由於變換數據流將整個過程分割成了輸入、變換和輸出三個部分,因此,對軟件結構的映 射也就可以是在總控模塊之下,將軟件分為輸入、變換、輸出三個部分。為了減輕總控模塊的 控制負擔,可以針對這三個部分,分別設置控制模塊,由此獲得對各個區段的有效控制。

圖 5-29 是基於變換流的高層框架圖。

 

(3)下層模塊

當軟件結構的高層框架被確定下來以后,接着需要考慮的是那些涉及具體操作的下級模 塊。為了確定下級模塊,並能夠按照一定規則 將這些下級模塊掛接到上面的框架上去,有必要對變換數據流進行分段研究。

(1)輸入部分

一般情況下,可以把來源於外部端口的數 據流稱為物理輸入點,而把由輸入過程進入到變 換中心的數據流稱為邏輯輸入點。圖 5-28 中的 輸入部分從“物理輸入點”到“邏輯輸入點”, 其模塊掛接規則是從“邏輯輸入點”往“物理輸入點”進行搜索,所遇到的每一個處理框可以作 為一個功能模塊依次掛接到“輸入控制”模塊之下。

(2)變換部分

圖 5-28 中的變換中心涉及“計算 1”與“計算 2”兩個處理框。可以將這兩個處理框對應 為功能模塊直接掛接到“變換控制”模塊之下。

(3)輸出部分

一般情況下,可以把由變換中心流向輸出過程的數據流稱為邏輯輸出點,而把由輸出過程 流向外部端口的數據流稱為物理輸出點。圖 5-28 中的輸出過程從“邏輯輸出點”到“物理輸出 點”,其模塊掛接規則是從“邏輯輸出點”往“物理輸出點”搜索,所遇到的每一個處理框可以 當做一個模塊依次分層掛接。 依照上述方法,可以獲得對圖 5-28 中的變換數據流的軟件結構映射,產生的軟件結構如 圖 5-30 所示。

 

2.事務流分析與設計

(1)事務流

當輸入的數據流可以引發多個不同的事務活動流程,並且數據流圖中有一個明顯的事務調 度中心時,這種數據流被稱為事務數據流。其特征如圖 5-31 所示。需要注意事務流中的事務調 度中心與變換流中的變換中心的區別,事務調度中心並不對輸入數據進行加工,而只是根據不 同的輸入數據作出不同的事務流程選擇。

 

 

 

 

(2)軟件結構

事務數據流以事務調度中心為核心,在此之前為接收事務,在此之后為事務分流處理。因 此,基於事務流的軟件結構映射也就可以是在總控模塊之下將軟件分為接收事務與事務活動兩 個部分。為了減輕總控模塊的控制負擔,可以針對這兩個部分分別設置控制模塊,例如“接收 事務控制”模塊、“調度事務控制”模塊,以獲得對各個區段的有效控制。 在事務流軟件框架確定以后,接着需要考慮其下層模塊的掛接。對此,以“事務調度中心” 為起點,分別搜索事務輸入流與事務活動流,將所遇到的每一個處理框當做一個功能模塊依次 掛接到“接收事務”模塊或 “調度事務”模塊之下。 依照上述方法,可以獲得對圖 5-31 中的事務數據流的軟件結構映射,產生的軟件結構如 圖 5-32 所示。

3. 混合流分析與設計

前面分別討論了變換分析與事務分析。其中,變換分析是軟件結構設計的主要方法,大部 分軟件系統都可以按照變換分析方法進行設計。但是,在很多情況下僅使用變換分析是不夠的, 還需要采用其他方法,事務分析就是一種非常有效的方法。例如商業數據處理系統,其主要組 成部分就往往使用事務處理方法進行設計。 軟件系統也可以是變換流與事務流的混合,如圖 5-33 所示為典型的變換流與事務流的混 合。對於這樣的系統,通常采用變換分析為主、事務分析為輔的方式進行軟件結構設計。其一 般設計思路如下:
 

(1)首先利用變換分析方法把軟件系統分為輸入、變換和輸出三個部分,由此設計出軟件 系統的上層構架,例如頂層和第一層模塊。

(2)然后根據數據流圖各部分的結構特點,適當地選擇變換分析或事務分析,由此設計出 軟件系統的下層構架。 如圖 5-33 中的混合數據流,即可以根據上述設計思路進行軟件結構映射,由此可以產生 出如圖 5-34 所示的軟件結構初始方案。

 

4.設計舉例

問題:“郵件檢測與計價電子儀器系統”軟件結構設計。 該問題數據流如圖 5-35 所示。這是一個典型的變換流問題,圖中數據流已被划分為輸入、 變換和輸出三個部分,並具有以下特征:

(1)輸入部分

有兩個輸入支路。支路一:用於輸入與檢驗郵件投遞參數,包括郵件種類、投遞地區、郵 資計價標准等參數;支路二:用於接收郵包傳感信號並檢測郵包,包括郵包重量、郵包封裝狀 態、郵包違禁狀態等信號。

(2)變換部分

包括計算單件郵資、累計郵資、處理不合格郵包等變換處理,分別用於合格郵包的郵資計 價和不合格郵包的處理提示。

(3)輸出部分

有四個輸出支路,包括:顯示單件郵資、顯示郵資總費用、打印票據、顯示不合格郵包處 理提示。 基於上述對數據流的分析,可以方便地根據變換流的結構映射規則產生出它所對應的軟件 基本結構。 該問題軟件結構如圖 5-36 所示。

 

 5. 數據庫結構設計

數據庫技術產生於 20 世紀 70 年代初期,從這個時期起,數據庫技術經歷了層次型、網狀 型、關系型三種模型。在數據庫應用早期,由於層次型、網狀型具有的性能優勢,它們占據了 初期階段的主流位置。但從 20 世紀 80 年代起,隨着計算機性能的迅速提高,關系型數據庫所具有的數學計算方面的優勢受到了重視,它逐漸成為主流數據庫,並得到了層次型、網狀型不 曾有過的更加廣泛的應用。例如 Oracle、SQL Server 這些耳熟能詳的通用大型數據庫都是關系 型數據庫。 數據庫就是與特定主題或目標相聯系的信息的集合,例如人事數據庫、工資數據庫等。數 據庫的作用是能夠為軟件系統提供后台數據存儲與運算。許多應用系統需要依賴數據庫提供數 據服務,尤其是一些信息管理系統,則更是以數據庫為中心進行部署。 與一般數據文件比較,數據庫具有以下方面的優越性:

(1)數據庫具有特殊的數據存儲結構,例如,關系型數據庫中的表結構,更加適宜對數據 進行有效的組織、存儲和檢索。

(2)數據庫具有更加完善的數據完整性約束機制,例如,可以通過設置和字段相關的主鍵、 外鍵,從而建立起數據表集之間的關聯;可以設置對數據字段、記錄的檢驗規則,以限制數據 存儲范圍。

(3)數據庫能夠實現數據存儲結構與數據表現形式的有效隔離,例如,可以通過數據視圖 而獲得對數據表集更加有效的應用組合。 本節將簡要介紹數據庫的結構設計,並將從邏輯結構設計和物理結構設計這兩個方面分別 給予說明。

 

1.邏輯結構設計

需求分析中已建立了有關數據庫的數據關系模型。但是,數據關系模型是基於對用戶應用 域的分析而構造的,是一個有關現實數據環境的數據庫概念模型。顯然,這種接近於現實世界 的概念模型與計算機世界之間的距離太大了,不能夠直接向數據庫實現過渡。因此,為了方便 數據庫的創建,需要將數據庫概念模型進行轉換,建立一種更加接近計算機世界的數據庫模型。
 概要設計中需要建立的有關數據庫的邏輯結構,就是一種與計算機世界更加接近的數據模 型,它提供了有關數據庫內部構造的更加接近於實際存儲的邏輯描述,因此能夠為在某種特定 的數據庫管理系統上進行數據庫物理創建提供便利。

(1)設計數據庫

在關系型數據庫中,數據是以數據表為單位實現存儲的。因此,數據庫邏輯結構設計首先 需要確定的就是數據庫中的諸多數據表。

可以按照以下規則從數據關系模型中映射出數據庫中的數據表來。

a.數據關系模型中的每一個實體應該映射為數據庫邏輯結構中的一個數據表。另外,實 體的屬性對應於數據表的字段,實體的碼對應於數據表的主鍵。

b.數據關系模型中的每一個 n : m 關系也應該映射為數據庫邏輯結構中的一個數據表。 另外,與該關系相連的各實體的碼以及關系本身的屬性,應該映射為數據表的字段;而與該關 系相連的各實體的碼,則需要組合起來作為關系數據表的主鍵。

c.數據關系模型中的每一個 1 : n 關系可以映射為一個獨立的數據表(映射規則類似 n
 : m 關系)。但在更多情況下,這個 1 : n 關系則是與它的 n 端對應的實體組合起來映射為一個數 據表。當 1 : n 關系是與 n 端對應實體合並組成數據表時,組合數據表的字段中需要含有 1 端 實體的碼屬性。

d.數據關系模型中的每一個 1 : 1 關系可以映射為一個獨立的數據表,也可以與跟它相 連的任意一端或兩端的實體合並組成數據表。實際上,兩個依靠 1 : 1 關系聯系的數據表可以 設置相同的主鍵,為了減少數據庫中的數據表的個數,往往將它們合並為一個數據表。合並方 法是將其中一個數據表的全部字段加入到另一個數據表中,然后去掉其中意義相同的字段(包 括意義相同但名稱不同的字段)。 圖 5-37 是一個用於描述教師、課程、學生三者之間關系的數據關系模型圖。可以按照上 述規則對這個數據關系模型進行映射,由此可以產生出以下數據表結構: 教師(教師編號,姓名,性別,職稱,學歷) 課程(課號,課名,計划課時,學分) 學生(學號,姓名,性別,專業,班級) 講授(教師編號,課號,實際課時) 學習(學號,課號,成績)

 

(2)規范數據表


 從數據關系模型映射出來的數據表是直接建立在用戶應用域基礎上的數據表。實際上,同 一個數據關系模型可以有許多種不同的數據表組合。為了使數據庫邏輯結構更加科學合理,設 計過程中,一般還需要按照關系數據庫規范原理對數據表進行規范化處理,由此可消除或減少 數據表中存在的不合理現象,例如數據存儲冗余、數據更新異常。 關系數據庫規范原理是基於數據冗余程度提出的,包含第一范式(1NF)、第二范式(2NF) 、 第三范式(3NF)、BC 范式(BCNF)、第四范式(4NF)和第五范式(5NF)。其中,第一范式規范 化程度最低,數據表內部多余聯系最多,數據冗余最大;第五范式規范化程度最高,數據表內 部幾乎沒有多余的聯系,數據冗余最小。 顯然,通過提高數據表范式級別可以降低數據表中的數據冗余,並可減少由於數據冗余造 成的數據更新異常。但是,為了提高數據表范式級別,就需要清除數據表內部的多余聯系,這 就需要對數據表進行分解。 值得注意的是,對數據表的分解大都會使對數據的查詢操作復雜起來(例如多表聯接操作),由此會降低數據查詢性能。 在數據庫實際應用中,為了既能使數據冗余與數據更新異常現象有所減少,又能使數據查 詢性能不會出現顯著下降,大多選用第三范式作為設計優化依據。

下面是對數據表中第一范式、第二范式和第三范式的描述。

  a.第一范式 數據表中的每一個字段值都必須是不可再進行分割的原子數據。

  b.第二范式 滿足第一范式條件,而且已經消除數據表中可能存在的非關鍵字段對關鍵字段集中個別字 段的部分依賴關系。也就是說,每一個非關鍵字段都只能由整個關鍵字段集決定,而不能由關 鍵字段集中的個別字段決定。

  c.第三范式 滿足第二范式條件,而且已經消除數據表中可能存在的非關鍵字段之間的傳遞依賴關系。 也就是說,每一個非關鍵字段都只能由關鍵字段集決定,而不能由非關鍵字段集決定。 一般情況下,如果數據表中的數據需要經常更改,這個數據表可以選用第三范式,甚至 BC 范式。但如果數據表中的數據不會更改或很少更改,卻經常需要查詢,並且要求有較高的查詢 性能,則可以選擇第二范式,甚至第一范式。

(3)關聯數據表

關聯數據表就是將數據關系模型中數據實體之間的關系在數據庫邏輯結構中明確體現出 來,它們將作為建立數據表之間參照完整性規則的依據。 圖 5-38 是數據庫的邏輯模型圖,其中的連線表示了數據表之間的關聯,連線帶箭頭一端 為主表,另一端為從表。其中,標記 PK 表示主表中的主鍵,標記 FK 表示從表中的外鍵。主表 與從表的關聯就建立在主表的主鍵字段集和從表的外鍵字段集之間。

(4)設計數據視圖

數據視圖也稱做虛表,原因在於數據視圖與數據表一樣,都可以將數據以記錄集合形式表 現出來。但是,數據視圖是面向系統前端應用的不同用戶的局部邏輯層。因此,它與面向系統后台全局數據存儲的數據表也就有着許多不同之處。 一般說來,數據表具有相對穩定的存儲結構,它所存儲的數據是具體的,並最終會以物理 形態在數據庫中出現。然而,數據視圖卻是面向用戶的外模式,它並不涉及具體的數據存儲, 而只是嵌入在數據庫中的 SQL 查詢操作,因此可以根據用戶的應用需要進行比較靈活的數據組 合,滿足不同用戶的數據應用需要。 數據視圖的作用是能夠使數據表現與數據存儲之間進行有效的邏輯隔離。實際上,數據視 圖為數據庫前端應用提供了許多便利。例如,可以使用一些更符合前端用戶習慣的數據名稱, 可以根據用戶對數據的特殊需要進行專門的數據視圖定義,可以使數據庫中的數據具有更高的 安全性,可以簡化前端程序員對數據庫的復雜編程等。

 

2.物理結構設計

數據庫最終是要存儲在物理設備上的。數據庫在物理設備上的存儲結構與存取方法稱為數 據庫的物理結構。為一個給定的邏輯數據模型選取一個最適合於應用的物理結構的過程,就是 數據庫的物理結構設計。 數據庫物理結構設計總是需要依賴於給定的計算機系統,例如,所選用的 DBMS 的特點, 需要開發的應用系統對處理頻率和響應時間的要求等。

 

(1)數據存儲結構

在確定數據庫中數據的存儲結構時,需要綜合考慮數據存取時間、存儲空間利用率和維護 代價這三方面的因素。並且,這三個方面還常常是相互矛盾的,例如,消除一切冗余數據雖然 能夠節約存儲空間,但往往會導致檢索代價的增加,因此必須進行權衡,選擇一個折中方案。 為了提高系統性能,有必要根據數據應用情況將易變部分與穩定部分、經常存取部分和存 取頻率較低部分分開存放。例如數據庫數據備份、日志文件備份等,由於只在故障恢復時才使 用,而且數據量很大,可以考慮存放在磁帶上。

(2)數據索引與聚集

為了提高對數據表中數據的查詢速度,可以在數據表的字段或字段集上建立索引。需要注 意的是,索引雖然可以提高查詢速度,但索引卻需要占用磁盤空間,並且會降低數據更新速度。 因此,對於是否設置索引,往往需要根據實際應用進行權衡。如果數據需要頻繁更新或磁盤空 間有限,則不得不限制索引個數。 許多關系型 DBMS 還提供了聚集索引功能,與一般索引比較,它能夠帶來更高的查詢效率。 但必須注意的是,聚集索引只能提高對某些特定字段的查詢性能,而且會帶來更大的維護開銷 和存儲空間消耗。因此,只有在聚集字段是最主要的查詢字段時,才有建立聚集的必要。

(3)數據完整性

為了使數據庫中的數據更加便於維護,還需要在數據庫中建立數據完整性規則,包括實體 完整性和參照完整性。 實體完整性是指數據庫對數據表中記錄的惟一性約束。為了使數據表具有實體完整性,需 要在數據表中設置主鍵,由此可確保數據表中的每一條記錄都是惟一的,也就是說不會出現重 復記錄。 數據庫參照完整性則是指建有關聯的數據表之間存在的“主表”對“從表”的一致性約束。由此可使從表中外鍵字段的取值能夠受到主表中主鍵字段取值的限制。例如,只有當主表的主 鍵字段中存在該值后,從表的外鍵字段才能取用該值;並可使得當主表中主鍵字段值更改時, 從表中對應的外鍵字段值可以自動同步更新,或使得當主表中有記錄刪除時,從表中外鍵字段 值和主表中主鍵字段值相同的相關記錄也被一同刪除。

小結:

1.設計過程與任務 概要設計中首先需要進行的是系統構架設計,然后是軟件結構、數據結構等方面的設計。 主要有以下幾個方面的設計任務:制定規范、系統構架設計、軟件結構設計、公共數據結構設 計、安全性設計、故障處理設計、可維護性設計、編寫文檔、設計評審。

2.系統構架設計

(1)集中式結構 集中式系統由一台計算機主機和多個終端設備組成。其具有非常好的工作穩定性和安全保 密性。但系統建設費用、運行費用比較高,靈活性不夠好,結構不便於擴充。

(2)客戶機/服務器結構 客戶機/服務器結構依靠網絡將計算任務分布到許多台不同的計算機上,但通過其中的服 務器計算機提供集中式服務。其優越性是結構靈活、便於系統逐步擴充。

(3)多層客戶機/服務器結構 •  兩層結構:將信息表示與應用邏輯處理都放在了客戶機上,服務器只需要管理數據庫 事務。

•  三層結構:將兩層結構的客戶機上的容易發生變化的應用邏輯部分提取出來,並放到一 個專門的“應用服務器”上。

•    B/S 結構:是 Web 技術與客戶機/服務器結構的結合。其優點是不需要對客戶機進行專 門的維護。

(4)組件對象 分布式結構通過組件進行計算分布。它依賴於對象中間件建立,具有靈活的構架,系統伸 縮性好,能夠給系統的功能調整與擴充帶來便利。

3.軟件結構設計 軟件結構設計是對組成系統的各個子系統的進一步分解與規划。主要設計內容有:確定模 塊元素、定義模塊功能、定義模塊接口、確定模塊調用與返回、進行結構優化。

(1)模塊概念

•  模塊化:使用構造程序,可使軟件問題簡化。

•  抽象化:概要設計中的模塊被看成是一個抽象化的功能黑盒子。

•  信息隱蔽:每個模塊的內部實現細節對於其他模塊來說是隱蔽的。

(2)模塊的獨立性 軟件系統中每個模塊都只涉及自己特定的子功能,並且接口簡單,與軟件中其他模塊沒有 過多的聯系。一般采用耦合和內聚這兩個定性的技術指標進行度量。耦合用來反映模塊相互關聯程度,模塊間連接越緊密,耦合性就越高。內聚用來反映模塊 內元素的結合程度,模塊內元素結合越緊密,則內聚性就越高。為提高模塊獨立性,要求模塊 高內聚、低耦合。 耦合形式由低至高是:非直接耦合、數據耦合、控制耦合、公共耦合、內容耦合。 內聚形式由低至高是:偶然內聚、邏輯內聚、時間內聚、過程內聚、通信內聚、順序內聚、 功能內聚。

(3)設計建模

•  軟件結構圖:由 Yourdon 於 20 世紀 70 年代提出,被廣泛應用於軟件結構設計中,能夠 有效說明軟件中模塊之間的調用與通信。

•    HIPO 圖:由美國 IBM 公司推出。其中,H 圖用於描述軟件的分層調用關系,作用類似軟 件結構圖,IPO 圖用於說明描述模塊的輸入—處理—輸出特征。

(4)軟件結構優化 主要優化設計原則有:使模塊功能完整、 使模塊大小適中、使模塊功能可預測、盡量降 低模塊接口的復雜程度、使模塊作用范圍限制在其控制范圍之內、模塊布局合理。

4.面向數據流的結構設計

(1)變換分析 軟件結構由輸入、變換和輸出三個部分組成。

(2)事務分析 軟件結構由接收事務與事務活動兩個部分組成。

(3)混合流分析與設計 軟件系統是變換流與事務流的混合。對於這樣的系統,通常采用變換分析為主、事務分析 為輔的方式進行軟件結構設計。

5. 數據庫結構設計

(1)邏輯結構設計

•  設計數據表

•  規范數據表

•  關聯數據表

•  設計數據視圖

(2)物理結構設計

•  數據存儲結構

•  數據索引與聚集

•  數據完整性


免責聲明!

本站轉載的文章為個人學習借鑒使用,本站對版權不負任何法律責任。如果侵犯了您的隱私權益,請聯系本站郵箱yoyou2525@163.com刪除。



 
粵ICP備18138465號   © 2018-2025 CODEPRJ.COM