如何計算整個Java項目的cyclomatic complexity?我對每種方法都有複雜性,但是如何將它們彙總爲一個數字度量標準?任何想法或現有方法?如何計算項目的圈複雜度(不是類/函數)?
我不是在尋找一種工具,而是一種算法。
簡單平均難以奏效,因爲有許多複雜性方法,複雜度並不低,但對代碼庫(在大多數情況下)並不重要。
如何計算整個Java項目的cyclomatic complexity?我對每種方法都有複雜性,但是如何將它們彙總爲一個數字度量標準?任何想法或現有方法?如何計算項目的圈複雜度(不是類/函數)?
我不是在尋找一種工具,而是一種算法。
簡單平均難以奏效,因爲有許多複雜性方法,複雜度並不低,但對代碼庫(在大多數情況下)並不重要。
我發現公式:
TCC = Sum(CC) - Count(CC) + 1
TCC: Total CC
Sum(CC): Sum of CC of all functions
Count(CC): Number of functions
來源:http://www.aivosto.com/project/help/pm-complexity.html
但也許是太有限了。
另一個想法是將程序的調用圖看作程序本身,並計算調用圖的CC。節點將由他們的CC加權。 (我不知道這是否可行,它只是一個想法)
我不知道這是否會有所幫助,但我只是想告訴我的想法。您可以使用全局深度計數器獲取方法調用深度並在每次方法調用時更新它。 您可以手動在這裏的每個方法中看到相同的代碼片段,但可能會有一個將代碼自動注入到所有方法的解決方案。利用堆棧跟蹤長度的級別,我認爲可以計算總體複雜度。
public class Cyclomatic
{
public static int max = Integer.MIN_VALUE;
static void a()
{
b();
int temp = Thread.currentThread().getStackTrace().length;
if (temp > max)
max = temp;
}
static void b()
{
c();
int temp = Thread.currentThread().getStackTrace().length;
if (temp > max)
max = temp;
}
static void c()
{
int temp = Thread.currentThread().getStackTrace().length;
if (temp > max)
max = temp;
}
public static void main(String[] args)
{
a();
System.out.println(max);
}
}
輸出:
5
整本書都是寫在代碼度量,那麼你是幸運的,你問一個更具體的問題。對於Java圈複雜度,可以找到超過5或6的圈複雜度的方法的數量(在此選擇數字)。如果這個數字超過了你方法數量的一定百分比,那麼整體圈複雜度就很差。對於百分比來說,一個好的數字完全取決於項目的規模,所以也許不是隻用方法的數量來劃分,而是可以減少分部中的方法數量,方法是讓數量較大的方法緩慢增長,例如隨着項目的發展,嘗試使其更穩定的平方根或對數。
也許是這樣的:
public double evaluateCyclomaticComplexity(List<MethodStat> methodStats) {
int bad = 0;
for (MethodStat methodStat : methodStats)
if (methodStat.getCyclomaticComplexity() >= 6)
bad++;
double denominator = Math.sqrt(methodStats.size());
return bad * 100.0/denominator;
}
這裏返回的數字越小越好。對於真的不好的項目,這將返回大於100的東西。
分母函數應該表示隨着代碼庫的增長,複雜性增長的快慢。通常情況下,隨着代碼增長,您希望每個函數的CC值更低,以便它能夠保持可維護性,所以隨着項目大小的增加,增長速度會越慢越好。
對它進行測試,調整等等。最終,代碼度量標準很難得到恰到好處,我可以在閱讀關於使用數字來表示「可維護性」的開源軟件的幾篇期刊論文後證明。如果在這裏花費了足夠的時間,那麼我們在這裏可以提出的任何事情都可能會大大改善。