如何降低if条件下的圈复杂度



如果条件如下:

if( condition1 || condition2 || condition3 || condition4 || condition5)

在条件相互独立的情况下,代码的复杂性往往很高,有没有办法重构这个逻辑来降低复杂性?

这里的条件可以表示进行验证并返回布尔值的方法。

为了清晰起见,我添加了一个代码片段:

public void doSomething(boolean val, boolean val2, boolean val3, boolean val4, boolean val5, boolean val6)
{
if(val || val2 || val3|| val4|| val5|| val6)
{
System.out.println("hello");
}
else{
System.out.println("hello world");
}
}

以上片段的复杂性为7。

我该如何减少?

可以为每个条件填充布尔标志,并在if语句中使用这些标志。在我看来,这也会提高可读性。

在这种特殊情况下,我会使此代码更加通用:

public void doSomething(boolean... val) {
for (boolean v : val) {
if (v) { 
System.out.println("hello");
return;
}
}
System.out.println("hello world");
}

这将允许您在方法中不携带任何数量的参数,如果此方法中的逻辑是真的This(即,如果任何参数是true,则执行ACTION#1,否则执行ACTION#2)。

编辑后:

"以上片段的复杂性为7">

我认为问题在于您用来衡量复杂性的工具

如果更换

if(val || val2 || val3|| val4|| val5|| val6)

通过

boolean condition = val || val2 || val3|| val4|| val5|| val6;          
if(condition)

现在的复杂性是什么?


在开发中,圈复杂度通常指代码流中的潜在路径。它通常与嵌套的条件块足够相关。

我们讨论了具有重要圈复杂度的代码,如箭头代码,因为嵌套级别绘制了一种箭头。

在您的示例代码中,这不是问题,因为您只有三个可能的路径:

public void doSomething(boolean val, boolean val2, boolean val3, boolean val4, boolean val5, boolean val6)
{
if(val || val2 || val3|| val4|| val5|| val6)
{
System.out.println("hello");
}
else{
System.out.println("hello world");
}
}
  • 第一个路径:if(val || val2 || val3|| val4|| val5|| val6)
  • 第二条路径:else{
  • 第三条路径:else和方法末尾之间的代码

代码的可能路径越少,读取、测试和维护就越容易。

在过于简单的情况下,您可以通过不使用else语句来降低复杂性。删除潜在路径:

public void doSomething(boolean val, boolean val2, boolean val3, boolean val4, boolean val5, boolean val6)
{
if(val || val2 || val3|| val4|| val5|| val6)
{
System.out.println("hello");
return;
}
System.out.println("hello world");           
}

但很明显,您的示例过于简单,无法体现与复杂性相关的严重问题
这是您的示例代码的修改版本,其中的复杂性问题是如何重构代码以降低循环复杂性。

public void doSomething(boolean val, boolean val2, boolean val3, boolean val4, boolean val5, boolean val6)
{
if(val || val2 || val3|| val4|| val5|| val6)
{
if (condition){
if (val8 && val9){
...
} 
else {
if (condition2 && condition3){
System.out.println("hello");
}
}
}
}
else{
System.out.println("hello world");
}
}

一般来说,为了降低圈复杂度,你必须减少可能的路径数量。你可以做到:

  • 通过避免不需要的else
  • 对分离的条件语句进行分组,而条件语句可以是单个语句
  • 当条件允许时退出方法,而不等待单个退出点

最新更新