孔慶玲,胡志軍,劉 英,馮 陽
(中國電子科技集團公司第五十四研究所,河北石家莊050081)
軟件越復雜,一方面在開發(fā)和維護過程中所消耗的資源也越多,所以軟件的復雜性可以作為軟件所需資源投入量的一個間接度量;另一方面在設計中引入錯誤的可能性也越大,這是一種合乎邏輯的推理,也是一個為實驗驗證的事實。盡管軟件復雜性與軟件中的錯誤數(shù)未必呈現(xiàn)出簡單的正比關(guān)系,但是存在這種正相趨勢是肯定無疑的。軟件不可靠的根本原因是軟件中存在錯誤,所以軟件復雜性可以作為軟件可靠性的一種間接度量。復雜性度量是軟件開發(fā)過程中有應用前景的一個度量。借助這個度量,設計人員在接受設計任務之初,可以從已有的性質(zhì)相似的程序中獲得經(jīng)驗數(shù)據(jù),對現(xiàn)在所面臨問題的復雜程度做出判斷,借助于復雜性度量還可以對若干設計方案的困難程度加以比較。
目前比較流行的有3種程序復雜性度量方法:Halstead、McCabe和 Thayer。Halstead使用統(tǒng)計的方法研究程序的復雜性,按照程序中的運算符和操作數(shù)的總數(shù)對程序的復雜性加以度量。McCabe以程序邏輯流程圖的分析為基礎,建立復雜性的度量。Thayer按程序的邏輯關(guān)系、接口、運算特征和輸入/輸出的特點來度量程序的復雜性。下面就這3種復雜性度量技術(shù)分別進行分析。
Halstead認為程序的復雜性可以用程序的運算符總數(shù)與操作數(shù)總數(shù)之和來反映,這個總數(shù)和稱為Halstead程序長度。為了得出Halstead程序長度的表達式,可以把程序視為由運算符、操作數(shù)交替組成的符號序列,在這些符號序列中,有 η1個不同的運算符符號和 η2個不同的操作數(shù)符號。屬于運算符符號的有+、-、>、<、IF THEN ELSE和DO WHILE等,屬于操作數(shù)符號的有變量、常數(shù)、字符串變量和字符串常數(shù)等,η1與η2的總和構(gòu)成程序的詞匯表。注釋和其他非執(zhí)行語句不屬于詞匯表的范圍。
Halstead將程序的生成等價于如下的隨機過程,首先從詞匯表中隨機選擇一個運算符符號,然后從詞匯表中隨機選擇一個操作數(shù)符號,這個交替過程一直持續(xù)下去,直到最后一個從未用過的運算符符號或操作數(shù)符號被選中時,程序的生成才結(jié)束,這時字符串長度的期望值可以按統(tǒng)計規(guī)律求出。
為了簡化分析過程,首先研究由 η個符號組成的詞匯表中的字符串的生成過程。可以觀察到在這個過程中,它產(chǎn)生出許多字符串,字符串長度是小于等于η,用SLk表示第k個字符串的長度,它表示出現(xiàn)一個以前的字符串中沒有出現(xiàn)過的字符時,字符串的字符數(shù)。所以當所有的 η個字符都被用到時,總的字符串長度是各個字符串長度之和,即
假定各個字符串的產(chǎn)生是相互獨立的,對SLη求期望值,則
第k+1個字符串中包含S各字符的概率可表示為:
因此第k+1個字符串長度的期望值為:
簡化后可得:
所以,
簡化后可得:
右邊的累加和式的每一項都小于1,即
應用于運算符符號可得:
應用于操作數(shù)符號可得:
按照Halstead的假設,運算符符號和操作數(shù)符號是交替選用的,所以總的字符串長度滿足:
取上限作為總的字符串長度的近似值,因此,
這就是Halstead程序長度的表達式,使用這個關(guān)系式時,不可將程序長度與程序的語句數(shù)相混淆。
在設計開始時,可以使用Halstead程序長度的表達式估計程序的長度。進入概要設計階段后,設計人員通常已經(jīng)能夠估計出程序需用的運算符符號數(shù),根據(jù)需要的輸入變量數(shù)目,輸出變量數(shù)目,中間變量數(shù)目及常數(shù)數(shù)目就可以預計出使用的操作數(shù)符號數(shù)目,因此按照Halstead程序長度的表達式可以預計出程序的長度。5個程序的預計結(jié)果如表1所示。
表1 Halstead復雜性度量技術(shù)試驗結(jié)果
Thayer認為程序的復雜性是由程序的內(nèi)在因素決定的,這些因素主要有5個:①邏輯復雜性,與程序的分支、循環(huán)語句等有關(guān);②接口復雜性,涉及程序與其他應用程序和系統(tǒng)程序的接口;③計算復雜性,與程序中的賦值語句及其所包含的算數(shù)運算符有關(guān);④輸入輸出復雜性,與程序的輸入及輸出語句有關(guān);⑤程序的可讀性,與程序的注釋語句有關(guān)。
1.2.1 邏輯復雜性
用LTOT表示每一個分程序或模塊的邏輯復雜性,其定義是:
式中,LS為邏輯語句數(shù);EX為可執(zhí)行語句數(shù);LLOOP為循環(huán)復雜性度量;LIF為IF條件語句復雜性度量;LBR為分支復雜性度量。
LLOOP可按下列各式計算:
式中,mi為分程序在第i嵌套層中的循環(huán)次數(shù);Wi為權(quán)系數(shù);Q為分程序中的最大嵌套層數(shù);系數(shù)1 000是按循環(huán)在邏輯復雜性LTOT中的相對重要性賦予的。
LIF可按下式計算:
式中,ni為分程序在第i嵌套層中的IF條件語句數(shù);Wi為權(quán)系數(shù);Q為分程序中的最大嵌套層數(shù);系數(shù)1 000是按IF語句在邏輯復雜性LTOT中的相對重要性賦予的。
LBR可按下式計算:
式中,NBR是分程序中的分支數(shù);系數(shù)0.001是按邏輯復雜性分支中分支系數(shù)的相對重要性賦予的。
1.2.2 接口復雜性
接口復雜性用CINF表示,其定義是:
式中,AP為分程序與應用程序接口數(shù);SYS為分程序與系統(tǒng)程序接口數(shù),系數(shù)0.5是用來反映系統(tǒng)程序接口與應用程序接口的相對重要性。
1.2.3 計算復雜性
計算復雜性用CC表示,其定義是:
式中,CS為程序中計算語句數(shù);∑CS為系統(tǒng)中各個分程序的計算語句之和;∑LTOT為系統(tǒng)中各個分程序的邏輯復雜性之和。
1.2.4 輸入輸出復雜性
輸入輸出復雜性用CI/O表示,其定義是:
式中,SI/O為分程序中的輸入輸出語句數(shù);∑SI/O為系統(tǒng)中各個分程序的輸入輸出語句之和。
1.2.5 可讀性
可讀性用UREAD表示,UREAD實際上是一個非復雜性度量,因為程序的可讀性越高,復雜性越小,其定義是:
式中,TS為程序中可執(zhí)行語句和非執(zhí)行語句之和,不包括注釋語句;COM為注釋語句數(shù)。
1.2.6 分程序復雜性
在定義了分程序復雜性的5個子度量之后,用CTOT表示分程序復雜性,其定義是:
式中,包括了0.1,0.2,0.4,-0.1四個權(quán)系數(shù),用來權(quán)衡各個子度量對程序復雜性影響的程度;UREAD的權(quán)系數(shù)取負值是由可讀性的特殊屬性決定的。
1.2.7 復雜性與軟件錯誤的關(guān)系
Thayer假設軟件錯誤數(shù)與程序復雜性是線性相關(guān)的。這個假設是否合理需要通過試驗來驗證。做了3個試驗,試驗分析了A、B、C、D和E5個分系統(tǒng),第1個試驗是用分程序復雜性度量CTOT與程序錯誤數(shù)作回歸直線;第2個試驗是用邏輯復雜性度量LTOT與程序錯誤數(shù)作回歸直線;第3個試驗試是在CTOT中刪去LTOT項后,與程序錯誤數(shù)作回歸直線。試驗結(jié)果如表2所示,作為近似分析,軟件錯誤數(shù)與程序復雜性線性相關(guān)的假設在一定范圍內(nèi)是可以采用的。
表2 軟件錯誤數(shù)與程序復雜性線性相關(guān)試驗結(jié)果
在構(gòu)造程序流程圖時,需要標識出1個起點和1個終點,從起點出發(fā)引1條有向弧,連接程序的第1個處理步驟節(jié)點,稱為入口點,簡單程序的入口點只有1個,大多數(shù)程序的入口點不止1個,這樣的程序流程圖應從起點出發(fā)引若干條有向弧。對程序中最后處理的語句節(jié)點稱為出口點,從出口點用1條有向弧通向終點。許多程序的出口點不止1個,都要用有向弧與圖的終點相連接。程序中順序執(zhí)行的無分支語句,可以用1個節(jié)點來表示,這樣的簡化不會影響回路數(shù)的計算,反而使計算變得更簡單。程序執(zhí)行到IF THEN ELSE語句時,將產(chǎn)生分支,在程序流程圖上要用相應的有分支的有向弧來表示。
為了將圖論中的復雜性度量用于程序的復雜性度量,必須保證程序流圖是強連接的,為此可用虛線畫1條從終端出發(fā),與起點相連的有向弧,這時網(wǎng)絡中的任何1個節(jié)點,至少存在1條通路通向其他任意一個節(jié)點,因而滿足了圖論中強連接的條件,程序的復雜性可以用V(G)=m-n+1表示,m為圖中弧的數(shù)目,n為節(jié)點數(shù),該式稱為程序的循環(huán)復雜性度量,又稱為McCabe復雜性度量。
關(guān)于循環(huán)復雜性度量,McCabe認為主要用途是反映程序質(zhì)量的好壞,他指出所有采用從頂向下結(jié)構(gòu)設計的模塊的V(G)都小于或等于10;他發(fā)現(xiàn)循環(huán)復雜性大的程序通常也是慣于出錯的程序。
為了使可靠性分配合理和可行,從工程上考慮,必須處理好3個方面的問題:分系統(tǒng)的重要程度、分系統(tǒng)的調(diào)用狀況和分系統(tǒng)的復雜性系數(shù)。
分系統(tǒng)的重要程度是指分系統(tǒng)發(fā)生失效后,對系統(tǒng)功能影響的程度。分系統(tǒng)k的重要程度可用重要度系數(shù)Uk表示,Uk的數(shù)值可通過工程分析確定。如果分系統(tǒng)k發(fā)生失效后將使系統(tǒng)失效或造成更嚴重的后果,則Uk取值為1;如果分系統(tǒng)k發(fā)生失效后,只引起較輕的損失,Uk取值可小于1。
軟件在運行時,各個分系統(tǒng)只能逐個調(diào)用,在系統(tǒng)總的運行時間中,各個分系統(tǒng)的運行時間互不相同,用調(diào)用系數(shù)Ik表示分系統(tǒng)k的調(diào)用狀況,可計算為:
式中,Wk為第k個分系統(tǒng)被調(diào)用的次數(shù)。在設計的早期根據(jù)經(jīng)驗估計出各個分系統(tǒng)的調(diào)用次數(shù)就可確定調(diào)用系數(shù)。
軟件可靠性分配中分系統(tǒng)的復雜性系數(shù)Ck的確定方法是借鑒軟件復雜性度量的概念,將各個分系統(tǒng)的復雜性度量經(jīng)過變換得出分系統(tǒng)的復雜性系數(shù)。用CXk表示第k個模塊的復雜性度量,它可以是Halstead度量、McCabe度量、Thayer度量或其他的度量。用于可靠性指標分配的復雜性系數(shù)為:
在綜合考慮了分系統(tǒng)的重要度、調(diào)用狀況和復雜性后,分系統(tǒng)k應分配的失效率ˉλk的計算式為:
式中,λs為系統(tǒng)的失效率指標。該式適用于軟件可靠性分配的基本關(guān)系式,體現(xiàn)了對復雜性大的分系統(tǒng)分配的失效率大一些,對于重要程度大的和調(diào)用較頻繁的分系統(tǒng),分配的失效率小一些。
在系統(tǒng)開發(fā)早期,分析人員掌握的信息非常有限,這時可以對各分系統(tǒng)的指令數(shù)做出粗略估計,用指令計數(shù)法作為復雜性度量進行可靠性指標分配,在開發(fā)過程進入概要設計階段,設計人員掌握了各個分系統(tǒng)使用的運算符和操作數(shù)的信息時,可以用Halstead復雜性度量對預分配加以調(diào)整。Halstead復雜性度量顯然比指令計數(shù)法更能反應程序的特征,經(jīng)過調(diào)整的復雜性系數(shù)及可靠性指標分配值也更合理。隨著設計的深入,Thayer復雜性度量、McCabe復雜性度量及節(jié)點復雜性度量都可選用。
[1]蔡開元.軟件可靠性工程基礎[M].北京:清華大學出版社,1995.
[2]黃錫滋.軟件的可靠性與安全性[M].北京:科學出版社,1993.