简体   繁体   English

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

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

In an if condition as following: 在if条件中如下:

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

Where conditions are independent of each other, the code complexity tends to be high, is there a way to refactor this logic to reduce complexity? 在条件彼此独立的情况下,代码复杂性往往很高,有没有办法重构这个逻辑以降低复杂性?

The conditions here can represent methods which do a validation and return a boolean value. 这里的条件可以表示进行验证并返回布尔值的方法。

I am adding a code snippet for clarity: 我为了清楚起见添加了一个代码段:

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

The complexity of the above snippet is 7. 上述代码段的复杂性为7。

How can I reduce it? 我怎样才能减少它?

May be get boolean flags populated for each condition and using those flags in if statement. 可以获取为每个条件填充的布尔标志,并在if语句中使用这些标志。 That would improve readability as well in my opinion. 在我看来,这也会提高可读性。

In this particular case I would make this code more universal: 在这种特殊情况下,我会使这个代码更通用:

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

    System.out.println("hello world");
}

This will allow you do not carry about number of arguments in method, if your logic inside this method is really this (ie do ACTION #1 if any of arguments is true , otherwise do ACTION #2). 这将允许你不在方法中携带大量的参数,如果你在这个方法中的逻辑真的是这个(即如果任何参数为true ,则执行ACTION#1,否则执行ACTION#2)。

After your edit : 编辑后:

"Complexity of the above snippet is 7" “上述代码片段的复杂性为7”

I think that the problem is the tool you are using to measure the complexity. 我认为问题是您用来衡量复杂性的工具。

If you replace it 如果你更换它

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

by 通过

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

what is the complexity now ? 现在复杂性是多少?


In development, cyclomatic complexity generally refers to potential paths in the code flow. 在开发中,圈复杂度通常是指代码流中的潜在路径。 It is often enough related to nested conditional blocks. 它通常与嵌套条件块有关。

We talk about code that has a important cyclomatic complexity as arrow code as the nested levels draw a kind of arrow. 我们讨论具有重要圈复杂度的代码作为箭头代码,因为嵌套级别绘制了一种箭头。

In your sample code it is not a problem as you have only three possible paths : 在您的示例代码中,这不是问题,因为您只有三个可能的路径:

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");
        }
    }
  • First path : if(val || val2 || val3|| val4|| val5|| val6) 第一条路径: if(val || val2 || val3|| val4|| val5|| val6)
  • Second path : else{ 第二条路径: else{
  • Third path : code between the else and the end of the method 第三条路径: else和方法结束之间的代码

Less a code have possible paths, more is it easier to read, to test, and to maintain it. 较少的代码有可能的路径,更容易阅读,测试和维护它。

In your too simple case you could reduce the complexity by using not the else statement. 在您太简单的情况下,您可以通过使用else语句来降低复杂性。 Which delete a potential path : 删除潜在路径:

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

But clearly your examples are too simple to manifest serious issues related to complexity. 但显然,您的示例太简单,无法表现出与复杂性相关的严重问题。
Here is a modified version of your sample code where the complexity questions about refactoring the code to reduce the cyclomatic complexity. 以下是示例代码的修改版本,其中复杂性问题涉及重构代码以减少圈复杂度。

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

Generally to reduce the cyclomatic complexity you have to reduce the number of possible paths. 通常,为了减少圈复杂度,您必须减少可能路径的数量。 You can achieve it : 你可以实现它:

  • by avoiding not required else 通过避免不需要else
  • grouping condition statements that are separated while it could be a single statement that 分组条件语句,它们可以是单个语句而分开
  • exiting of the method when a condition allows to do it and not waiting for a single exit point. 当条件允许执行该方法而不等待单个退出点时退出该方法。

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

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