概念
圈复杂度也称条件复杂度,是一种衡量代码复杂度的标准。它可以用来衡量一个模块判定结构的复杂程度,数量上表现为独立现行路径条数,也可以理解为覆盖所有情况最少使用的测试用例数。圈复杂度大说明程序代码的判断逻辑复杂,可能难以维护。
计算方法
V(G) = E - N + 2;
其中,E表示控制流图中边的数量,N表示控制流图中点的数量。
下面举例说明,如if-else,while,until和正常的顺序:
squence
A;
B;
if - else
A;
if(some_condition)
then
B;
else
C;
end if
D;
while
A;
while(some_condition)
do
B;
end
C;
until
A;
repeat
B;
until(some_condition);
C;
举个例子:
void func(){
a;
while(A)
{
if(B || C)
b;
c;
}
if(D && E) {
d;
for(F)
{
if(G || H || I)
e;
}
}
if(J && K)
h;
i;
};
那么上面的复杂度为:
A(while)+B(if)+C(if)+D(if)+E(if)+F(for)+G(if)+H(if)+I(if)+J(if)+K(if)+1 = 12
注意||和&&也会被算作一个判定节点
圈复杂度的意义
一般来说,圈复杂度大存在很大的出错风险。另外在测试的时候,一个很好的用例设计经验:创建与圈复杂度值相等的测试用例,以此提高用例对代码的分支覆盖率。
降低圈复杂度的方法
-
提炼函数,将复杂的分支隔离,换成call func()调用函数。
-
使用break,return代替控制标记。
-
使用数据结构,算法。
-
多态取代条件式,设计模式替换。
-
简化条件判断。
举个例子:string fun(string key) { if(key == "A") { return "a"; } else if(key == "B") { return "b" } else if(key == "C") { return "c" }; return string; }改成
string fun(string key) { map<string,string> maps; maps["A"]="a"; maps["B"]="b"; maps["C"]="c"; return maps[key]; }
常用工具
- OCLint(C语言),GMetrics(Java),PyMetrics(Python),JSComplexity(js)
- Lizard,sourcemonitor(支持多种语言)
- sonarqube(平台)

圈复杂度,又称条件复杂度,是评估代码复杂性的指标,与测试用例数和程序维护难度有关。计算公式为V(G) = E - N + 2,其中E表示边数,N表示点数。高圈复杂度增加错误风险,建议通过提炼函数、使用break/return、简化条件等方式降低。常用的圈复杂度检查工具有OCLint、GMetrics、PyMetrics、JSComplexity、sourcemonitor和sonarqube。
591

被折叠的 条评论
为什么被折叠?



