196.整體設計

第5章  整體設計程序員

 

整體設計任務算法

• 系統方案設計數據庫

    劃分出組成系統的物理元素——程序、文件、數據庫、人工過程和文檔等等,可是每一個物理元素仍然處於黑盒子級。數據結構

• 體系結構設計app

    設計軟件的結構,肯定系統中每一個程序是由哪些模塊組成的,以及這些模塊相互間的關係。數據庫設計

 

5.1  設計過程

兩個主要階段組成:ide

系統設計階段:肯定系統的具體實現方案;模塊化

結構設計階段:肯定軟件結構。函數

 

 

    典型的整體設計過程包括下述9個步驟:工具

1. 設想供選擇的方案

    以數據流圖爲基礎,尋找實現目標系統的各類不一樣的方案。

 

2. 選取合理的方案

    至少選取低成本、中等成本和高成本的三種方案。

    對每一個合理的方案分析員都應該準備下列資料:

(1) 系統流程圖;

(2) 組成系統的物理元素清單;

(3) 成本/效益分析;

(4) 實現這個系統的進度計劃。

 

3. 推薦最佳方案

 

4. 功能分解

肯定軟件結構,從實現角度把複雜的功能進一步分解。

一般分爲兩個階段完成:

    結構設計:肯定程序由哪些模塊組成,以及這些模塊之間的關係。整體設計階段的任務

    過程設計:肯定每一個模塊的處理過程。

                        詳細設計階段的任務

 

    功能分解致使數據流圖的進一步細化,同時用IPO圖簡要描述細化後每一個處理的算法。

 

5. 設計軟件結構

     把模塊組織成良好的層次系統,頂層模塊調用它的下層模塊以實現程序的完整功能,每一個下層模塊再調用更下層的模塊,從而完成程序的一個子功能,最下層的模塊完成最具體的功能。

   軟件結構(即由模塊組成的層次系統)能夠用層次圖或結構圖來描繪,第5.4節將介紹這些圖形工具。

    若是數據流圖已經細化到適當的層次,能夠直接從數據流圖映射出軟件結構,這就是第5.5節中將要講述的面向數據流的設計方法。

 

6. 設計數據庫

 

7. 制定測試計劃

    開發早期考慮測試問題,可提升軟件的可測試性。

 

8. 書寫文檔

(1) 系統說明。主要內容包括:

    系統流程圖描繪的系統構成方案,組成系統的物理元素清單,成本/效益分析;

    精化的數據流圖,用層次圖或結構圖描繪的軟件結構,用IPO圖描述的各個模塊的算法,模塊間的接口關係等。

(2) 用戶手冊

(3) 測試計劃

(4) 詳細的實現計劃

(5) 數據庫設計結果

 

9. 審查和複審

 

 

5.2  設計原理  

好的設計準則

• 模塊化

• 抽象

• 逐步求精

• 信息隱藏和局部化

• 模塊獨立

 

5.2.1  模塊化

模塊: 是由邊界元素限定的相鄰程序元素(例如,數聽說明,可執行的語句)的序列,並且有一個整體標識符表明它。按照模塊的定義,過程、函數、子程序和宏等,均可做爲模塊。

   

模塊化:把程序劃分紅獨立命名且可獨立訪問的模塊,每一個模塊完成一個子功能,把這些模塊集成起來構成一個總體,能夠完成指定的功能,知足用戶的需求。

模塊化的根據:把複雜的問題分解成許多容易解決的小問題,原來的問題也就容易解決了。

模塊化的後果:隨着模塊數目增長,設計模塊間接口所須要的工做量也將增長。

    根據這兩個因素,得出了圖中的總成本曲線。每一個程序都有一個最適當的模塊數目M,使得系統的開發成本最小。

   

圖5.1 模塊化和軟件成本

 

5.2.1  模塊化優勢

• 使軟件結構清晰,容易設計也容易閱讀和理解。

•提升軟件的可靠性。

     程序錯誤侷限在有限的模塊中,使軟件容易測試和調試。

•提升了軟件的可修改性。

     即便有變更,每每只涉及少數幾個模塊,

• 有助於軟件開發工程的組織管理。

      一個大型程序由許多程序員分工編寫,分配技術熟練的程序員編寫困難的模塊。

5.2.2  抽象

抽象:把事務類似的方面集中和歸納起來,暫時忽略它們之間的差別。

    抽象就是抽出事物的本質特性而暫時不考慮它們的細節。

5.2.3  逐步求精

Miller法則:一我的在任什麼時候候都只能把注意力集中在(7±2)個知識塊上。

逐步求精是人類解決複雜問題時採用的基本方法。

 

逐步求精其實是自頂向下的細化過程。

    高抽象級別定義的功能,僅做概念性地描述,沒有提供功能的內部工做狀況。

    求精要求設計者細化原始陳述,隨着每一個後續求精(即細化)步驟的完成,提供愈來愈多的細節。

 

    抽象與求精是一對互補的概念。

    抽象使得設計者可以說明過程和數據,同時卻忽略低層細節。

    求精則幫助設計者在設計過程當中逐步揭示出低層細節。

    這兩個概念都有助於設計者在設計演化過程當中創造出完整的設計模型。

5.2.4  信息隱藏和局部化

信息隱藏:一個模塊內包含的信息(過程和數據)對於不須要這些信息的模塊來講,是不能訪問的。

局部化:是指把一些關係密切的軟件元素物理地放得彼此靠近。

在模塊中使用局部數據元素是局部化的一個例子。有助於實現信息隱藏。

5.2.5  模塊獨立

    模塊獨立的概念是模塊化、抽象、信息隱藏和局部化概念的直接結果。

模塊獨立:具備獨立功能並且和其餘模塊之間沒有過多的相互做用的模塊。

模塊獨立的重要性:

第一,具備獨立模塊的軟件比較容易開發。

第二,獨立模塊比較容易測試和維護。

    錯誤傳播範圍小,容易測試與修改,須要擴充功能時可以「插入」模塊。

 

 模塊獨立程度的度量標準:內聚和耦合。

耦合:模塊間互相依賴(鏈接)的緊密程度;

內聚:模塊內部各個元素彼此結合的緊密程度。

 

1. 耦合

 影響耦合強度的因素

• 一個模塊對另外一個模塊的引用

• 一個模塊向另外一個模塊傳遞的數據量

• 一個模塊施加到另外一個模塊的控制的數量

• 模塊之間接口的複雜程度

 

耦合的類型

•         內容耦合  強

•         公共耦合  ¦

•         控制耦合  ¦

•         標記耦合  ↓

•         數據耦合  弱

 

 

 在軟件設計中應該追求儘量鬆散耦合。

 

    對模塊的測試或維護時,不須要對系統的其餘模塊有不少了解。

 此外,因爲模塊間聯繫簡單,發生在一處的錯誤傳播到整個系統的可能性就很小。

 

    所以,模塊間的耦合程度強烈影響系統的可理解性、可測試性、可靠性和可維護性。

 

 

數據耦合

數據耦合:模塊彼此間經過參數交換信息,交換的信息僅僅是數據。

 數據耦合是低耦合。系統中至少必須存在這種耦合,由於只有當某些模塊的輸出數據做爲另外一些模塊的輸入數據時,系統才能完成有價值的功能。

    通常說來,一個系統內能夠只包含數據耦合。

 

 

 

標記耦合
( Stamp coupled )

• 若兩個模塊間傳遞的參數中至少有一個是數據結構,如字符串或記錄,而且在模塊中僅用到該數據結構中的部分元素,則稱這兩個模塊之間存在標記耦合。

    在這種狀況下,被調用的模塊可使用的數據多於它確實須要的數據,將致使對數據的訪問失去控制,從而給計算機犯罪提供了機會。

 

 

 

控制耦合
(Control coupled)

控制耦合:一個模塊向另外一個模塊傳遞控制信息,接收信息的模塊的動做根據信息值進行調整。  

    控制耦合是中等程度的耦合,它增長了系統的複雜程度。在把模塊適當分解以後一般能夠用數據耦合代替它。

 

 

 

公共耦合
( Common coupled )

•兩個模塊共享全局的數據區域,稱他們爲公共耦合。

•不要使用全局變量

 

 

 

公共耦合

  耦合的複雜程度隨耦合模塊的個數而變化,隨個數的增長顯著增長。

     兩個模塊的公共耦合有兩種可能:

(1) 一個模塊往公共環境送數據,另外一個模塊從公共環境取數據。這是數據耦合的一種形式,是比較鬆散的耦合。

(2) 兩個模塊都既往公共環境送數據又從裏面取數據,這種耦合比較緊密,介於數據耦合和控制耦合之間。

 

 

內容耦合
( Content coupled )

•內容耦合的三種狀況:

•一個模塊修改另外一個模塊的語句 (Lisp 具備此種能力)

•一個模塊引用或者修改另外一個模塊內部的數據

•一個模塊不經過正常入口而跳轉到另外一個模塊的內部

 

 

模塊獨立性與耦合的關係

 

 

 

 總之,耦合是影響軟件複雜程度的一個重要因素。應該採起下述設計原則:

 儘可能使用數據耦合,少用控制耦合和標記耦合,限制公共環境耦合的範圍,徹底不用內容耦合。

 

 

 

2. 內聚

 內聚標誌一個模塊內各個元素彼此結合的緊密程度。理想內聚的模塊只作一件事情。

 度量一個模塊內部各成分之間相互關聯的強度

 

•         偶然內聚  弱

•         邏輯內聚

•         時間內聚

•         過程內聚  ↓

•         通訊內聚

•         順序內聚

•         功能內聚  強

 

 

偶然內聚
coincidental cohesion

    若是一個模塊的各成分之間毫無關係,則稱爲偶然內聚。

 

 

邏輯內聚
logically cohesive

幾個邏輯上相關的功能被放在同一模塊中。

 

 

時間內聚
Temporal cohesion

若是一個模塊完成的功能只是由於時間因素關聯在一塊兒。

 

 

 

時間內聚
Temporal cohesion

•Consider a module called "On_Really_Bad_Failure" that is invoked when a Really_Bad_Failure happens. The module performs several tasks that are not functionally similar or logically related, but all tasks need to happen at the moment when the failure occurs.

•The module might

cancel all outstanding requests for services

cut power to all assembly line machines

notify the operator console of the failure

make an entry in a database of failure records

 

 

過程內聚
procedurally cohesive

若是一個模塊內部的各個處理成分必須以特定的次序執行,則稱爲過程內聚。

 

通訊內聚
communicationally cohesive

若是一個模塊的全部成分都操做同一數據集或生成同一數據集,則稱爲通訊內聚。

 

 

 

順序內聚
sequentially cohesive

若是一個模塊的各個成分和同一個功能密切相關,並且一個成分的輸出做爲另外一個成分的輸入,則稱爲順序內聚。

 

 

 

 

功能內聚
functionally cohesive

模塊的全部成分對於完成單一的功能都是基本的。

 

 

設計時儘可能使用高內聚,低耦合模塊。

 

• 高內聚:儘可能使用內聚度高的模塊;中內聚也可;低內聚很壞,不要採用。

低內聚:偶然內聚,邏輯內聚,時間內聚

中內聚:過程內聚,通訊內聚

高內聚:順序內聚,功能內聚;

 

• 低耦合:儘可能使用數據耦合,少用控制耦合和標記耦合,限制公共耦合的範圍,徹底不用內容耦合。

 

 

5.3  啓發式規則

改進軟件設計,提升軟件質量的途徑。

•改進軟件結構提升模塊獨立性

•模塊規模應該適中

•深度、寬度、扇出和扇入應適中

•模塊的做用域應該在控制域以內

•力爭下降模塊接口的複雜性

•設計單入口和單出口的模塊

•模塊功能應該能夠預測

 

1. 改進軟件結構提升模塊獨立性

•下降耦合

•提升內聚

 

2. 模塊規模應該適中

•模塊規模:

不超過60行

超過30,可理解程度迅速降低

•模塊數量:

適中

 

模塊過大:每每是因爲分解不充分。

模塊太小:致使模塊數目過多,使系統接口複雜。能夠把它合併到上級模塊中去。

 

3. 深度、寬度、扇出和扇入都應適當

• 深度:表示軟件結構中控制的層數。

      能粗略地標誌一個系統的大小和複雜程度。若是層數過多,應考慮管理模塊是否過度簡單,可否適當合併。

• 寬度:軟件結構內同一個層次上的模塊總數的最大值。

      寬度越大系統越複雜。對寬度影響最大的因素是模塊的扇出。

 

扇出:是一個模塊直接控制(調用)的模塊數目。

     扇出過大意味着模塊過度複雜,須要控制和協調的下級模塊過多;扇出太小(例如老是1)也很差。

    一般是3或4(上限是5~9)。

扇出太大:缺少中間層次,應適當增長中間層次的控制模塊。

扇出過小:把下級模塊進一步分解成若干個子功能模塊,或者合併到它的上級模塊中去。

    分解或合併模塊應符合問題結構,不能違背模塊獨立原理。

 

扇入:代表有多少個上級模塊。扇入越大則共享該模塊的上級模塊數目越多,這是有好處的。

    好的軟件結構一般頂層扇出比較高,中層扇出較少,底層模塊有高扇入。

    系統的模塊結構呈現爲「葫蘆形」。

 

 

 

4. 模塊的做用域應該在控制域以內

• 模塊的做用域:受該模塊內一個斷定影響的全部模塊的集合。

• 模塊的控制域:模塊自己以及全部直接或間接從屬於它的模塊的集合。

    例如,在圖5.2中模塊A的控制域是A、B、C、D、E、F等模塊的集合。

    受斷定影響的模塊應在作出斷定的那個模塊的控制域以內。

 

 

圖5.2 模塊的做用域和控制域

 

5. 力爭下降模塊接口的複雜程度

    應該仔細設計模塊接口,使得信息傳遞簡單而且和模塊的功能一致。

 

6. 設計單入口單出口的模塊

    使模塊間避免出現內容耦合。當從頂部進入模塊而且從底部退出來時,軟件是比較容易理解的,所以也是比較容易維護的。

 

7. 模塊功能應該能夠預測

    只要輸入的數據相同就產生一樣的輸出,這個模塊的功能就是能夠預測的。

    帶有內部「存儲器」的模塊的功能多是不可預測的,不宜測試與維護。

 

 

5.4  描繪軟件結構的圖形工具  

5.4.1  層次圖和HIPO圖

層次圖:用來描繪軟件的層次結構。

    形式和描繪數據結構的層次方框圖相同,但表現的內容卻徹底不一樣。

•層次圖中的一個矩形框表明一個模塊,方框間的連線表示調用關係

•層次方框圖中的一個矩形框表明數據的子集,方框間的連線表示組成關係。

圖5.3是層次圖的一個例子。

  

圖5.3 正文加工系統的層次圖

 

 

HIPO: 「層次圖加輸入/處理/輸出圖」的英文縮寫。

    爲了能使HIPO圖具備可追蹤性,在H圖(層次圖)裏除了最頂層的方框以外,每一個方框都加了編號。編號規則和數據流圖的編號規則相同。

例如,圖5.3加了編號後獲得圖5.4。

    H圖中每一個方框對應一張IPO圖,描繪這個方框表明的模塊的處理過程。每張IPO圖內都應標出它所描繪的模塊在H圖中的編號。

 

圖5.4 帶編號的層次圖(H圖)

5.4.2  結構圖

     結構圖和層次圖相似,也是描繪軟件結構的圖形工具。

結構圖基本符號:

•方框——模塊

•方框間連線——模塊調用關係(上方的模塊調用下方的模塊)

•帶註釋的箭頭——模塊間傳遞的信息

•箭頭尾部空心圓——數據信息

•箭頭尾部實心圓——控制信息

 

 

圖5.5 結構圖的例子——產生最佳解的通常結構

 

    還有一些附加的符號,能夠表示模塊的選擇調用或循環調用。

   

 圖5.6 斷定爲真時調用A,爲假時調用B

 

圖5.7 模塊M循環調用模塊A、B、C

 

 

5.5 面向數據流的設計方法


5.5.1  概念

面向數據流的設計方法:把數據流圖中的信息流映射成軟件結構。信息流的類型決定了映射的方法。信息流有下述兩種類型。

 

1. 變換流

變換流:具備較明顯的輸入、變換(或稱主加工)和輸出界面的數據流圖。

參看圖5.8

 

圖5.8 變換流

 

2. 事務流

事務流:數據沿輸入通路到達一個處理T,這個處理根據輸入數據的類型在若干個動做序列中選出一個來執行。

此時數據流圖形狀如圖5.9,是「以事務爲中心的」。

圖5.9中的處理T稱爲事務中心,它完成下述任務:

(1) 接收輸入數據(輸入數據又稱爲事務);

(2) 分析每一個事務以肯定它的類型;

(3) 根據事務類型選取一條活動通路。

 

圖5.9 事務流

 

3. 設計過程

    圖5.10(見書96頁)說明了使用面向數據流方法逐步設計的過程。

 

 

5.5.2  變換分析

變換分析:把數據流圖按預先肯定的模式映射成軟件結構的一系列設計步驟的總稱。

 

 

下面經過一個例子說明變換分析的方法。

1. 例子

考慮汽車數字儀表板的設計。

假設的儀表板將完成下述功能:

(1) 經過模數轉換實現傳感器和微處理機接口;

(2) 在發光二極管面板上顯示數據;

(3) 指示每小時英里數(mph),行駛的里程,每加侖油行駛的英里數(mpg)等等;

(4) 指示加速或減速;

(5) 超速警告:若是車速超過55英里/小時,則發出超速警告鈴聲。

在需求分析階段創建起相應的數據流圖。

 

2. 設計步驟

第1步 複查基本系統模型。

複查的目的是確保系統的輸入數據和輸出數據符合實際。

第2步 複查並精化數據流圖。

應該對需求分析階段得出的數據流圖認真複查,而且在必要時進行精化。使數據流圖中每一個處理都表明一個規模適中相對獨立的子功能。

假設在需求分析階段產生的數字儀表板系統的數據流圖如圖5.11(見書97頁)所示。

第3步 肯定數據流圖具備變換特性仍是事務特性。

    通常地說,一個系統中的全部信息流均可以認爲是變換流,可是,當遇到有明顯事務特性的信息流時,建議採用事務分析方法進行設計。

     從圖5.11看出,數據沿着兩條輸入通路進入系統,而後沿着5條通路離開,沒有明顯的事務中心。

    所以能夠認爲這個信息流具備變換流的總特徵。

第4步 肯定輸入流和輸出流的邊界,從而孤立出變換中心。

    對於汽車數字儀表板的例子,設計人員肯定的流的邊界如圖5.12(見書98頁)所示。

第5步 完成「第一級分解」。

分解:就是分配控制的過程,對控制的自頂向下的分配----軟件結構。

    圖5.13說明了第一級分解的方法。位於軟件結構最頂層的控制模塊Cm協調下述從屬的控制功能:

輸入信息處理控制模塊Ca:協調對全部輸入數據的接收;

變換中心控制模塊Ct:管理對內部形式的數據的全部操做;

輸出信息處理控制模塊Ce:協調輸出信息的產生過程。

    數據流圖被映射成一個特殊的軟件結構,這個結構控制輸入、變換和輸出等信息處理過程。

 

圖5.13 第一級分解的方法

    對於數字儀表板的例子,第一級分解得出的結構如圖5.14所示。每一個控制模塊的名字代表了爲它所控制的那些模塊的功能。

 

圖5.14 數字儀表板系統的第一級分解

 

第6步 完成「第二級分解」。

第二級分解:就是把數據流圖中的每一個處理映射成軟件結構中一個適當的模塊。

完成第二級分解的方法是:

•從變換中心的邊界開始沿着輸入通路向外移動,把輸入通路中每一個處理映射成軟件結構中Ca控制下的一個低層模塊;

•而後沿輸出通路向外移動,把輸出通路中每一個處理映射成直接或間接受模塊Ce控制的一個低層模塊;

•最後把變換中心內的每一個處理映射成受Ct控制的一個模塊。

       圖5.15表示進行第二級分解的廣泛途徑。

 

圖5.15 第二級分解的方法

 

    對於數字儀表板系統的例子,第二級分解的結果分別用圖5.16,5.17和5.18描繪。

    這3張圖表示對軟件結構的初步設計結果。

 

圖5.16 未經精化的輸入結構

 

 

圖5.17 未經精化的變換結構

 

 

圖5.18 未經精化的輸出結構

 

第7步 使用設計度量和啓發式規則對第一次分割獲得的軟件結構進一步精化。

 根據模塊獨立原理進行精化。獲得儘量高的內聚、儘量鬆散的耦合。需對初步分割獲得的模塊進行再分解或合併。

    具體到數字儀表板的例子,對於從前面的設計步驟獲得的軟件結構,還能夠作許多修改:

• 輸入結構中的模塊「轉換成rpm」和「收集sps」能夠合併;

• 模塊「肯定加速/減速」能夠放在模塊「計算mph」下面,以減小耦合;

• 模塊「加速/減速顯示」能夠相應地放在模塊「顯示mph」的下面。

通過上述修改後的軟件結構畫在圖5.19中。

 

圖5.19 精化後的數字儀表板系統的軟件結構

 

5.5.3  事務分析

    在數據流具備明顯的事務特色時,也就是有一個明顯的「發射中心」(事務中心)時,仍是以採用事務分析方法爲宜。

事務分析的設計步驟和變換分析的設計步驟大部分相同或相似,主要差異僅在於:

    由數據流圖到軟件結構的映射方法不一樣。

 

    由事務流映射成的軟件結構包括一個接收分支和一個發送分支。

• 接收分支結構

    映射方法和變換分析映射出輸入結構的方法很相像。

    從事務中心的邊界開始,把沿着接收流通路的處理映射成模塊。

• 發送分支結構

    包含一個調度模塊,它控制下層的全部活動模塊;

    而後把數據流圖中的每一個活動流通路映射成與它的流特徵相對應的結構。

     圖5.20說明了上述映射過程。

 

 

圖5.20 事務分析的映射方法

5.5.4  設計優化

    對第一次分割獲得的軟件結構,總能夠根據模塊獨立原理和啓發式設計規則進行優化。

   爲了產生合理的分解,獲得儘量高的內聚﹑儘量鬆散的耦合,最重要的是,爲了獲得一個易於實現﹑易於測試和易於維護的軟件結構,應該對初步分割獲得的模塊進行再分解或合併。

    注意,設計優化應該力求作到在有效的模塊化的前提下使用最少許的模塊,以及在可以知足信息要求的前提下使用最簡單的數據結構。

5.6  小結

整體設計階段的基本目的:是用比較抽象歸納的方式肯定系統如何完成預約的任務,肯定系統的物理配置方案,肯定組成系統的每一個程序的結構。

整體設計階段主要由兩個小階段組成。

首先須要進行系統設計;而後進行軟件結構設計,肯定軟件由哪些模塊組成以及這些模塊之間的動態調用關係。

層次圖和結構圖是描繪軟件結構的經常使用工具。

 

在進行軟件結構設計時應該遵循的最主要的原理是模塊獨立原理。

抽象和求精是一對互補的概念。在進行軟件結構設計時就是由抽象到具體地構造出軟件的層次結構。

 

軟件工程師在開發軟件的長期實踐中積累了豐富的經驗,總結這些經驗得出一些頗有參考價值的啓發式規則。

自頂向下逐步求精是進行軟件結構設計的經常使用途徑;

若是已經有了詳細的數據流圖,也可使用面向數據流的設計方法,由數據流圖映射出軟件結構。

    這樣映射出來的只是軟件的初步結構,還必須根據設計原理而且參考啓發式規則,認真分析和改進軟件的初步結構,以獲得質量更高的模塊和更合理的軟件結構。

 

 

 

相關文章
相關標籤/搜索