圈複雜度數的是一段程式碼裡線性獨立的執行路徑有幾條,實作上等於分支點的數量加一——每個 if、每個迴圈條件、每個 case、每個布林運算子的短路點各加一。它的原始用途是估算「要完全覆蓋這段程式需要幾個測試案例」,所以它跟測試判準是同一個問題的兩端:複雜度給出案例數的下界,判準決定每個案例斷言什麼。

概念位置

它量的是單一函式的分支數,不量概念的完整性,也不量函式之間的耦合——跟突變分數的分工很清楚:這裡數的是路徑有幾條,那裡數的是那些路徑上的斷言擋不擋得住行為改變。這個射程決定了它當品質閘門時的行為:把一個十分支的函式切成四個各三分支的函式,總分支數不變而每個函式都合規——指標下降而閱讀時要重建的脈絡變多。機械約束買到被量測的那個數字那張卡用的正是這個度量當實例。

CRAP 度量把它跟覆蓋率合起來:CRAP(m) = C²(1 − cov)³ + C,其中 C 是圈複雜度、cov 是該函式的覆蓋率。滿覆蓋率時 CRAP 等於圈複雜度本身,所以「CRAP 低於 4」等價於「每個函式的複雜度不超過 3」。

可觀察訊號與例子

一個 if 加一個 for 加一個三元運算子的函式,複雜度是 4,完全覆蓋它至少要四個案例。同一段邏輯改用查表取代分支,複雜度會掉到 1 而行為不變——這是它與「這段程式難不難懂」脫鉤的地方:查表版可能更難懂,指標卻好看得多。

門檻設在 10 上下是工具的常見預設,出處是原始論文的建議值而不是實證;設在 3 是特定實驗的參數,不是通用建議。看到一個複雜度門檻時要先問這個數字從哪來。

設計責任

拿它當閘門的人要同時指定它量不到的那個維度該由誰檢查。可機械執行的是觸發——每個新產生的函式名都被問一次;判定那個名字對不對得回一個領域概念,仍然是人的工作,可以要求它在需求文件或領域詞彙表裡找得到對應。沒有配對這一步時,最便宜的達成方式(把違規處切碎)與真正的分解在指標上完全一樣。