圈複雜度計算器 - McCabe 指標工具

使用 McCabe 的圖形公式 M = E − N + 2P 或決策數快捷公式 M = D + 1 來計算圈複雜度,評估軟體品質。

選擇計算方法,輸入圖形指標或決策數,即可取得 McCabe 複雜度分數與風險等級。

圈複雜度計算器 - McCabe 指標工具
使用 McCabe 的圖形公式 M = E − N + 2P 或決策數快捷公式 M = D + 1 來計算圈複雜度,評估軟體品質。

當你有控制流程圖時使用此方法。統計有向邊數(E)、節點數(N)與連通分量數(P,單一函式通常為 1)。

關於圈複雜度計算器

圈複雜度是 Thomas J. McCabe 於 1976 年提出的軟體品質度量。它透過統計原始碼中的線性獨立路徑數量,量化程式的結構複雜度。複雜度越高,要覆蓋所有分支所需的測試案例就越多,程式也越難理解、修改與維護。 這項指標建立在圖論之上。程式被建模為控制流程圖(CFG),其中每個節點代表一個基本區塊——也就是只有單一入口與單一出口的一段直線式指令序列——每條有向邊則代表從一個區塊到另一個區塊的控制轉移。條件敘述、迴圈與例外處理器都會產生分支,進而增加邊的數量與獨立路徑的數量。 McCabe 公式為 M = E − N + 2P,其中 E 是 CFG 中的邊數,N 是節點數,P 是連通分量數(單一函式或程序通常為 1)。對於完全線性的程式,在沒有任何分支時,M 等於 1。每增加一個二元決策點,複雜度就會恰好增加 1。包含 k 個分支的 switch 敘述會讓複雜度增加 k,因為它引入了 k 條新路徑。 從實務角度看,更簡單的計數規則對結構化程式碼會得到相同答案:M = D + 1,其中 D 是決策點總數。決策點是任何能讓執行走向兩條以上路徑的結構:if 或 else-if 分支、switch 中的 case、for、while 或 do-while 迴圈標頭、三元運算子、會產生短路分支的邏輯 AND 或 OR,以及 catch 區塊。 業界指南通常將 1–4 視為低風險,5–7 視為中等風險,8–10 視為高風險(應考慮重構),10 以上視為非常高風險(強烈建議拆分函式)。複雜度值也給出了完成分支覆蓋所需的最少測試案例數:複雜度為 8 的函式至少需要 8 個測試案例才能覆蓋每條獨立路徑。 需要理解圈複雜度衡量與不衡量的內容。它不直接衡量程式碼行數、效能或演算法正確性。一個很長但完全順序執行的函式複雜度可能是 1,而一個條件巢狀很深的短函式複雜度可能高達 20。這項指標專門捕捉決策路徑結構,這是測試工作量的主要驅動因素,也是潛在缺陷最常見的來源。與程式碼審查及其他品質指標一起使用時,圈複雜度是識別應優先重構與測試函式的實用指南。

圈複雜度範例

三個範例展示了在真實程式結構中使用兩種計算方法的結果。

輸入M說明
E = 9, N = 8, P = 1M = 3圖形方法:9 − 8 + 2×1 = 3。一個包含兩個 if 敘述與一個迴圈的簡單函式。
D = 4 decisionsM = 5決策方法:4 + 1 = 5。一個包含兩條 if-else 鏈的函式;中等風險,5 個測試案例即可控管。
E = 14, N = 10, P = 1M = 6圖形方法:14 − 10 + 2 = 6。一個有 5 個分支的 switch;複雜度中等,值得為每個分支撰寫說明。

如何使用圈複雜度計算器

  1. 選擇計算方法。如果你已經繪製控制流程圖,或可以直接檢視程式碼的控制流程圖,就使用以圖形為基礎的方法。如果想透過統計決策關鍵字快速估算,就使用以決策為基礎的方法。
  2. 以圖形為基礎的方法:輸入邊數(E)、節點數(N)與連通分量數(P)。單一函式時 P 為 1;只有在一起分析多個不連通部分時才輸入實際數量。
  3. 以決策為基礎的方法:統計每個 if、else-if、case、for、while、do-while、三元運算子(?:)、catch,以及會產生新分支的短路邏輯運算子(&&、||)。將總數作為 D 輸入。
  4. 點擊計算。結果會顯示 McCabe 複雜度 M 與風險分類——低(1–4)、中(5–7)、高(8–10)或非常高(>10)。
  5. 將複雜度值視為完成分支覆蓋所需的最少測試案例數,並考慮對任何 M > 10 的函式進行重構。

圈複雜度常見問題

圈複雜度衡量什麼?
它衡量函式控制流程圖中的線性獨立路徑數量,也就是存在多少條不同的執行路徑。每增加一個決策點(if、迴圈、case),就會多一條路徑。這個值等於實現完整分支覆蓋所需的最少測試案例數。
什麼樣的圈複雜度算好?
McCabe 的原始建議是函式的 M 應不超過 10。1–4 為低風險,易於測試;5–7 為中等;8–10 為高風險;10 以上為非常高風險,強烈建議拆分為更小、更聚焦的函式。
圖形方法和決策計數方法一樣嗎?
對於結構化程式(沒有 GOTO 敘述),兩者結果相同。決策計數快捷法 M = D + 1 會統計每個分支關鍵字並加 1。圖形方法 M = E − N + 2P 則統計圖中的邊與節點。兩者捕捉的是同一層面的結構資訊。
switch 敘述裡的每個 case 都要單獨計算嗎?
是的。每個 case 標籤都是獨立分支,因此一個有 5 個 case 的 switch 會讓決策數增加 5(或讓 CFG 增加 5 條邊)。某些靜態分析工具只統計 case 群組數量,而不是單個 case;請務必查看工具文件,確保量測方式一致。
圈複雜度與測試有什麼關係?
複雜度值 M 等於至少需要多少個獨立測試案例,才能把每個分支都走過一遍。一個 M = 8 的函式至少需要 8 個精心設計的測試案例才能達成完整分支覆蓋。複雜度越高,測試工作量越大,缺陷機率越高,維護負擔也越重——這些都是將單一函式控制在 M = 10 以下的充分理由。
圈複雜度適用於所有程式語言嗎?
是的。只要語言具有條件與迭代控制結構,這個指標就適用。不同語言的決策點略有差異——Python 使用 elif,Ruby 使用 case/when,SQL 使用 CASE/WHEN——但計數原則相同。Java、Python、JavaScript、C# 以及大多數主流語言的自動化工具都將 McCabe 複雜度作為標準品質指標。