如何满足SonarLint java:S135规则并保持代码干净?

问题描述 投票:0回答:1

SonarLint 的规则 java:S135 说:

循环不应包含多个“break”或“continue” 陈述 Break 和 continue 语句的使用增加了复杂性 控制流并使理解程序逻辑变得更加困难。 为了保持良好的程序结构,不应应用它们 每个循环不止一次。当有更多时,此规则会报告问题 比循环中的一个 Break 或 continue 语句更重要。代码应该是 如果有多个,则进行重构以提高可读性。

并给出了这个例子:

for (int i = 1; i <= 10; i++) {     // Noncompliant; two "continue" statements
  if (i % 2 == 0) {
    continue;
  }

  if (i % 3 == 0) {
    continue;
  }
  // ...
}

应重构为:

for (int i = 1; i <= 10; i++) {
  if (i % 2 == 0 || i % 3 == 0) {
    continue;
  }
  // ...
}

但是看起来很奇怪。我有这个测试示例:

@Slf4j
public class TestService {

    public int test(List<String> input) {
        int count = 0;
        for (String s : input) {
            if ("ONE".equals(s)) {
                log.info("one was called");
                processOne(s);
                continue;
            }

            String something = getSomethingBy(s);
            if (something == null) {
                log.info("something is null");
                sendEmail();
                continue;
            }

            if ("TWO".equals(s) && "hz".equals(something)) {
                process(s);
                count++;
            }
        }
        return count;
    }

和 sonarLint 声称:

如果我将此代码更改为:

public int testGoodForSonarLint(List<String> input) {
        int count = 0;
        for (String s : input) {
            if ("ONE".equals(s)) {
                log.info("one was called");
                processOne(s);
            } else {
                String something = getSomethingBy(s);
                if (something == null) {
                    log.info("something is null");
                    sendEmail();
                } else if ("TWO".equals(s) && "hz".equals(something)) {
                    process(s);
                    count++;
                }
            }
        }
        return count;
    }

看起来很糟糕。我讨厌那个 if-else 下巴和地狱般的 {}。该代码看起来像一棵圣诞树。 这是2个继续。在实际代码中,我有 4 个。因此,并不总是可以像 SonarLint 所建议的那样进行重构:

if (i % 2 == 0 || i % 3 == 0) {
        continue;
      }

因为我需要在每种情况下做一些事情,而不仅仅是继续。

也许我不明白一些东西,但通过继续或中断来交互循环看起来比括号地狱更好和可读。你觉得怎么样,是否可以重写这段代码?如果是,您将如何重构我的示例?

java cycle sonarlint
1个回答
0
投票

您可以为迭代创建另一种方法并在其中

return

那么,它就不会在方法内跳转,而只是停止方法的执行。

@Slf4j
public class TestService {

    public int test(List<String> input) {
        int count = 0;
        for (String s : input) {
             count = processString(s, input);
        }
        return count;
    }
    private int processString(String s, int count){
        if ("ONE".equals(s)) {
            log.info("one was called");
            processOne(s);
            return count;
        }

        String something = getSomethingBy(s);
        if (something == null) {
            log.info("something is null");
            sendEmail();
            return count;
        }

        if ("TWO".equals(s) && "hz".equals(something)) {
            process(s);
            count++;
        }
        return count;
    }
}
© www.soinside.com 2019 - 2024. All rights reserved.