使用
本質複雜度至少在1980年代中期已被使用,圖靈獎得主佛瑞德·布魯克斯當時已開始使用本質複雜度及其反義詞偶然複雜度。他也在1995年時在《人月神話》中的沒有銀彈一段中提出他的新論點。
含義
若本質複雜度和循環複雜度並用時,本質複雜度有不同的含意。此時的本質複雜度是指一程式持續的將有良好結構的流桯控制指令改為單一敘述後,最後得到的循環複雜度。像if-then-else及while loop等控制結構都視為良好結構,因此不會增加本質複雜度。未限制使用的goto、break及continue指令會增加本質複雜度。
例如,以下的C語言程式片段的本質複雜度為1,因為內層的if指令及for循環都可以簡化為單一敘述。
for(i=0;i<3;i++) {if(a[i] == 0) b[i] += 2;}
以下的C語言程式片段的本質複雜度大於1,其內容是要找到z陣列中第一個全部為0的列,若找到了,設定i為列編號,若找不到了,設定i為-1
for(i=0;i<m;i++) {for(j=0;j<n;j++) {if(z[i][j] != 0) goto non_zero;}goto found;non_zero:}i = -1;found:
循環複雜度
循環複雜度(
Cyclomatic complexity)也稱為
條件複雜度或
圈複雜度,是一種
軟體度量,是由老托馬斯·J·麥凱布在1976年提出,用來表示程式的複雜度,其符號為
VG或是
M。循環複雜度由程式的
原始碼中量測線性獨立路徑的個數。此概念有些類似的量測文字複雜度的Flesch-Kincaid可讀性測試,不過方法不完全相同。
循環複雜度是由程式的
控制流圖來計算:有向圖的節點對應程式中個別的代碼,而若一個程式運行後會立刻運行另一代碼,會有邊連結二代碼對應的節點。圈複雜度可套用在程式的
子程式、
模組、
方法或
類別。
麥凱布首先提出一種稱為“基礎路徑測試”(Basis Path Testing)的
軟體測試方式,是測試程式中的每一線性獨立路徑,此情形的
測試用例個數即為程式的循環複雜度。
“循環複雜度”的名稱有時會讓人誤解,因為此複雜度不只計算程式中的循環(循環)個數。循環複雜度是指程式的控制流圖中,若將結束點到啟始點再增加一個邊時,控制流圖中的圈(幾個邊形成封閉路徑)的個數。
偶然複雜度
偶然複雜度(
Accidental complexity)是指
電腦軟體開發過程中所引入不必要的複雜度。偶然複雜度不是待求解問題的本質,相對而言,
本質複雜度和待求解問題的本質有關,是無法避免的。偶然複雜度一般是因為選用求解問題的方法時所引入的。
有時偶然複雜度可以歸因於像無效的規劃等錯誤,不過有時偶然複雜度是求解問題時伴隨產生的副作用。例如因為記憶體用完而產生的複雜度是一種偶然複雜度,但只要決定使用電腦求解問題,就會有在這種複雜度。
好的軟體架構、設計及實現可以將偶然複雜度降到最低,過多的偶然複雜度是一個
反面模式的例子。