VSCode 圈复杂度插件 CodeMetrics


VSCode 圈复杂度插件 CodeMetrics

圈复杂度(Cyclomatic Complexity)是一种代码复杂度的衡量标准。它可以用来衡量一个模块判定结构的复杂程度,数量上表现为独立现行路径条数,也可理解为覆盖所有的可能情况最少使用的测试用例数。圈复杂度大说明程序代码的判断逻辑复杂,可能质量低且难于测试和维护。程序的可能错误和高的圈复杂度有着很大关系。

圈复杂度主要与分支语句(if、else、,switch 等)的个数成正相关。

采用圈复杂度去衡量代码的好处

  1. 指出极复杂模块或方法,这样的模块或方法也许可以进一步细化。

  2. 限制程序逻辑过长。

McCabe&Associates 公司建议尽可能使 V(G) <= 10。NIST(国家标准技术研究所)认为在一些特定情形下,模块圈复杂度上限放宽到 15 会比较合适。

因此圈复杂度 V(G)与代码质量的关系如下:

1
2
3
V(G) ∈ [ 0 , 10 ]:代码质量不错; 
V(G) ∈ [ 11 , 15 ]:可能存在需要拆分的代码,应当尽可能想措施重构;
V(G) ∈ [ 16 , ∞ ):必须进行重构;
  1. 方便做测试计划,确定测试重点。

常用降低圈复杂度的方法

  1. 采用三元表达式
1
2
3
4
5
6
7
8
if (condition)
{
c = a;
}
else
{
c = b;
}

可修改为:

1
c = (condition) ? a : b;
  1. 合并条件表达式
1
2
3
4
if (a || b || c )
{

}

可修改为:

1
2
3
4
5
bool flag = a || b || c ;
if (flag)
{

}
  1. 拆分成子函数

  2. switch…case…可以使用Map

  3. 去掉没有必要的else

1
2
3
4
5
6
7
8
if (false)
{
return;
}
else
{
c = a;
}

可修改为:

1
2
3
4
5
if (false)
{
return;
}
c = a;
  1. 重构函数

举例:同一条件多处出现

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
if (list.empty())
{
if (a)
{
// do something 1...
}
}
else
{
if (a)
{
// do something 2...
}
}
if (a)
{
// do something 3...
}

可修改为:

1
2
3
4
5
6
7
8
9
10
11
12
if (a)
{
if (list.empty())
{
// do something 1...
}
else
{
// do something 2...
}
// do something 3...
}