複製鏈接
請複製以下鏈接發送給好友

軟件複雜度

鎖定
軟件複雜度遵守原則是簡單就是可靠,其複雜度在不斷變化。
中文名
軟件複雜度
基本原則
簡單就是可靠
複雜度
70年代軟件系統已經變得極其複雜
分    類
模塊、類和程序

軟件複雜度基本概念

在硬件的可靠性設計中,有一條基本原則“簡單就是可靠”。這個原則同樣也適合軟件,與功能的增多或增強相伴的是不斷升級與補丁。已經有若干種軟件複雜性的度量方法可供參考,其中McCabe QA是比較出色和實用的方法,它能夠計算出多種軟件複雜度,由此可對軟件進行檢查、分析和查明那些可能導致錯誤的代碼。

軟件複雜度複雜度

70年代,軟件系統已經變得極其複雜,無論是開發還是維護都是一項成本高昂的工作。人們意識到必須使軟件模塊化,以便於開發、測試和維護。為此,成立於1976的McCabe&Associates公司開發出了McCabe Cyclomatic Complexity Metric(圈複雜度)技術對軟件進行結構測試。Metric以軟件複雜度測量的數目為基礎,能幫助工程師識別難於測試和維護的模塊,圈複雜度已經成為評估軟件質量的一個重要標準。人們可以用圈複雜度對軟件的複雜度和質量進行衡量,來安排工程進度,在成本、進度和性能之間尋求平衡。

軟件複雜度種類

有模塊、類和程序三類複雜度。模塊複雜度包含了關於模塊的複雜度信息;類複雜度是針對那些使用McCabe面向對象特性的程序,它包含了關於類的複雜度信息;程序複雜度包含了關於程序的複雜度信息。
集成複雜度報告
對應於三種複雜度的是三種複雜度報告。如果一個報告的複雜度信息不只一種,那麼就把這些複雜度信息組合成新的報告。
集成複雜度信息只收集一個部件及其下級的信息。例如:如果一個程序級報告包含一個類複雜度,那麼只報告組成程序的類的信息,而不包含類組成的信息。
McCabe複雜度
McCabe複雜度是對軟件結構進行嚴格的算術分析得來的,實質上是對程序拓撲結構複雜性的度量,明確指出了任務複雜部分。McCabe複雜度包括:圈複雜度、基本複雜度、模塊設計複雜度、設計複雜度、集成複雜度、行數、規範化複雜度、全局數據複雜度、局部數據複雜度、病態數據複雜度。
McCabe複雜度的用途
軟件工程中,有三種使用McCabe複雜性度量的方式。
作為測試的輔助工具。McCabe複雜性度量的結果等於通過一個子程序的路徑數,因而需要設計同樣多的測試案例以覆蓋所有的路徑。如果測試案例數小於複雜性數,則有三種情況一是需要更多的測試;二是某些判斷點可以去掉;三是某些判斷點可用插入式代碼替換。
作為程序設計和管理指南。在軟件開發中,需要一種簡單的方式指出可能出問題的子程序。保持子程序簡單的通用方法是設置一個長度限制,例如50行或2頁,但這實際上是在缺乏測試簡明性的有效方法時無可奈何的替代方法。不少人認為McCabe度量就是這樣一種簡明性度量。但是要注意,McCabe度量數大的程序,不見得結構化就不好。例如,Case語句是良結構的,但可能有很大的McCabe度量數(依賴於語句中的分支數),這可能是由於問題和解決方案所固有的複雜性所決定的。使用者應當自己決定如何使用McCabe度量所提供的信息。
作為網絡複雜性度量的一種方法。Hall和Preiser提出了一種組合網絡複雜性度量,用於度量可能由多個程序員組按模塊化原理建立的大型軟件系統的複雜性。他們提出的組合度量公式為
式中 C1,...,Ck是各個模塊的複雜性;CN是網絡複雜性;W1和W2為權值。
McCabe複雜度即可用於度量各個模塊的複雜性,也可用於度量網絡複雜性。
Cyclomatic Complexity (v(G))圈複雜度
圈複雜度是用來衡量一個模塊判定結構的複雜程度,數量上表現為獨立路徑的條數,即合理的預防錯誤所需測試的最少路徑條數,圈複雜度大説明程序代碼可能質量低且難於測試和維護,經驗表明,程序的可能錯誤和高的圈複雜度有着很大關係。
獨立路徑組成的集合稱為基本路徑集合,獨立路徑數就是指基本路徑集合中路徑的數量。基本路徑集合不是唯一的,獨立路徑數也就不唯一。因此,圈複雜度是最大獨立路徑數。 [1] 
計算方法
節點是程序中代碼的最小單元,邊代表節點間的程序流。如果一個模塊流程圖有e條邊n個節點,它的圈複雜度V(G)=e-n+2,典型的V(G)max=10。
優點
避免軟件中的錯誤傾向;指出極複雜模塊,這樣的模塊也許可以進一步細化;度量測試計劃,確定測試重點;在開發過程中通過限制程序邏輯,指導測試過程;指出將要測試的區域;幫助測試人員確定測試和維護對象;與所用的高級程序設計語言類型無關。
應用
圈複雜度指出為了確保軟件質量應該檢測的最少基本路徑的數目。在實際中,測試每一條路經是不現實的,測試難度隨着路徑的增加而增加。但測試基本路徑對衡量代碼複雜度的合理性是很必要的。McCabe & Associates建議圈複雜度到10,因為高的圈複雜度使測試變得更加複雜而且增大了軟件錯誤產生的概率。
提示:
圈複雜度度量是測量在一個軟件模塊中的分支數目,在所有的開發週期中都要使用。
圈複雜度度量以軟件的結構流程圖為基礎。控制流程圖描述了軟件模塊的邏輯結構。一個模塊在典型的語言中是一個函數或子程序,有一個入口和一個出口,也可以通過調用/返回機制設計模塊。軟件模塊的每個執行路徑,都有與從模塊的控制流程圖中的入口到出口的節點相符合的路徑。
“Cyclomatic”來源於非直接連接基本測試周期的數目,更重要的是,也通過直接相連的圖表給出獨立路徑的數目。通過圖表的相關性,一個節點可到達另一個節點。
圈複雜度度量也可作為模塊基本流程圖路徑的數目,其重點在於模塊線形組合後,所產生的路徑數目是最小的。
對圈複雜度的限制
有許多好方法可以用來限制圈複雜度。過於複雜的模塊容易出錯,難於理解、測試、更正,所以應當在軟件開發的各個階段有意識地限制複雜度,許多開發者已經成功地實現把對軟件複雜度的限制作為軟件項目的一部分,儘管在確切的數目上略微有些爭議。最初支持的數目是10,支持數目可達15。但是,只應當在條件較好的情況下使數目大於10,例如開發者非常有經驗,設計合乎正式標準,使用現代化的程序語言、結構程序、代碼預排和先進的測試計劃。換句話説,開發團隊可以選擇超過10的限制數目,但是必須根據經驗進行一些取捨,把精力花在比較複雜的模塊上。
Essential Complexity (ev(G))基本複雜度
基本複雜度是用來衡量程序非結構化程度的,非結構成分降低了程序的質量,增加了代碼的維護難度,使程序難於理解。因此,基本複雜度高意味着非結構化程度高,難以模塊化和維護。實際上,消除了一個錯誤有時會引起其他的錯誤。
計算方法
將圈複雜度圖中的結構化部分簡化成一個點,計算簡化以後流程圖的圈複雜度就是基本複雜度。
優點
衡量非結構化程度;反映代碼的質量;預測代碼維護量,輔助模塊劃分;與所用的高級程序設計語言類型無關。
應用
當基本複雜度為1,這個模塊是充分結構化的;當基本複雜度大於1而小於圈複雜度,這個模塊是部分結構化的;當基本複雜度等於圈複雜度,這個模塊是完全非結構化的。
Module Design Complexity (iv(G))模塊設計複雜度
模塊設計複雜度是用來衡量模塊判定結構,即模塊和其他模塊的調用關係。軟件模塊設計複雜度高意味模塊耦合度高,這將導致模塊難於隔離、維護和複用。
計算方法
模塊設計複雜度是從模塊流程圖中移去那些不包含調用子模塊的判定和循環結構後得出的圈複雜度,因此模塊設計複雜度不能大於圈複雜度,通常是遠小於圈複雜度。
優點
衡量模塊對其下層模塊的支配作用;衡量一個模塊到其子模塊進行集成測試的最小數量;定位可能多餘的代碼;以複雜的計算邏輯和設計來區分模塊;是設計複雜度(S0)和集成複雜度(S1)計算的基礎;與所用的高級程序設計語言類型無關。
Design Complexity (S0)設計複雜度
設計複雜度以數量來衡量程序模塊之間的相互作用關係,它提供了系統級模塊設計複雜度的概況,有助於衡量進行自底向上集成測試的效果,而且提供了全面衡量程序設計規格和複雜度的數據,不反映獨立模塊的內部情況。高設計複雜度的系統意味着系統各部分之間有着複雜的相互關係,這樣系統將難以維護。
S0是程序中所有模塊設計複雜度之和,計算公式如下:
優點
可應用於完整的軟件,也可應用於任何子系統;衡量代碼的質量;指出一個模塊整體的複雜度,反映了每個模塊和其內部模塊的控制關係;揭示了程序中模塊調用的複雜度;有助於集成複雜度的計算。
Integration Complexity (S1)集成複雜度
集成複雜度是為了防止錯誤所必須進行的集成測試的數量表示,另一種説法是程序中獨立線性子樹的數目,一棵子樹是一個有返回的調用序列。就像圈複雜度是測試路徑的數目,而集成複雜度是程序或其子系統的獨立線性子樹。
計算方法
一個程序的集成複雜度和一個模塊的圈複雜度是非常相似的,必須計算對程序進行完全測試所需集成測試的數目。S1的計算公式:
S1=S0-N+1
N是程序中模塊的數目。
優點
有助於集成測試的實施;量化集成測試工作且反映了系統設計複雜度;有助於從整體上隔離系統複雜度。
Number of Lines (nl)行數
行數是模塊中總的行數,包括代碼和註釋。
優點:
計算簡單;與所用的高級程序設計語言類型無關;指出了模塊的行數(即模塊的規模),規模小的模塊易於理解和維護。
Normalized Complexity (nv)規範化複雜度
規範化複雜度是圈複雜度除以行數。
計算方法
nv=v(G)/nl
優點
與所用的高級程序設計語言類型無關;定義那些有着顯著判定邏輯密度的模塊,這些模塊相對於其他常見規範模塊需要做更多的維護工作。
全局數據複雜度
全局數據複雜度(需有McCabe Data)量化了模塊結構和全局數據變量的關係,它説明了模塊對外部數據的依賴程度,同時度量了全局數據的測試工作,也描述了模塊之間的耦合關係,能反映潛在的維護問題。
對於如何跟蹤全局數據使用情況的更多信息,可以參考《McCabe Data in Using McCabe IQ Add-Ons》。
局部數據複雜度
局部數據複雜度(需有McCabe Data)量化了模塊結構和用户局部數據變量的關係,同時度量了局部數據的測試工作。
我們能夠使用McCabe Data的數據字典選擇單獨的數據元素,指出每個數據元素具體的數據類型。局部數據複雜度還提供了其他的數據選擇準則,量化了每個模塊中相應數據對模塊控制結構的影響。
關於數據字典的更多信息,參考文檔《McCabe Data in Using McCabe IQ Add-Ons.》。
病態數據複雜度
病態數據複雜度衡量一個模塊包含的完全非結構化成份的程度,標出向循環內部跳入的問題代碼,而這些部分具有最大的風險度,通常需要重新設計。
計算方法
所有的非結構部分除去向循環內跳入的結構,轉化為線結構,病態複雜度就等於簡化以後流程圖的圈複雜度。
優點
與所用的高級程序設計語言類型無關;指出了可靠性的問題,降低了維護風險;幫助識別極不可靠的軟件。
(Halstead 複雜度)
McCabe QA能夠為所選擇的語言產生Halstead Metrics複雜度。Halstead複雜度是以程序中出現的運算符和運算元為計數對象,以它們出現的次數作為計數目標(直接測量指標),然後據以計算出程序容量、工作量。
優點
不要求對程序結構進行深層次分析;能夠預測錯誤率;預測維護工作量;有利於項目規劃,衡量所有程序的複雜度;計算方法簡單;與所用的高級程序設計語言類型無關;眾多研究結構研究表明Halstead複雜度對於預測程序工作計劃和程序的Bug非常有用。
Line Count複雜度描述了Line Count複雜度並列出了它們的優點
Line Count Metrics(Line Count複雜度)
優點
軟件物理規模的度量;定義了具體的Line Count數據,例如註釋行和空行;協助指出難於理解的模塊。
參考資料
  • 1.    Watson A H,Mccabe T J..Structured testing:a testing methodology using the cyclomatic complexity metric.:NIST:Special Publication 500-235,,1996年9月