繁体   English   中英

如何减少if条件下的圈复杂度?

[英]How to reduce cyclomatic complexity in a if condition?

在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");
}

这将允许你不在方法中携带大量的参数,如果你在这个方法中的逻辑真的是这个(即如果任何参数为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
  • 分组条件语句,它们可以是单个语句而分开
  • 当条件允许执行该方法而不等待单个退出点时退出该方法。

暂无
暂无

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM