修复了Java中多个if条件的认知复杂性

时间:2020-11-05 08:38:29

标签: java sonarqube sonarqube-scan

这是我的代码,可以正常工作。但是当我推送代码时,声纳质量门由于认知复杂性而失败。解决此声纳问题的任何想法

            Graphics.DrawString(A.ToString, New Font("Arial", 50, FontStyle.Regular), New SolidBrush(Color.Black), New Point(220, 215), drawformat)

            Graphics1.TranslateTransform(50, 230)
            Graphics1.RotateTransform(-29)
            Graphics1.DrawString(B.ToString, New Font("Arial", 50, FontStyle.Regular), New SolidBrush(Color.Black), New Point(408, 119), drawformat)

            Graphics.DrawString(C.ToString, New Font("Arial", 50, FontStyle.Regular), New SolidBrush(Color.Black), New Point(820, 45), drawformat)

            Graphics2.TranslateTransform(910, 1010)
            Graphics2.RotateTransform(-90)
            Graphics2.DrawString(D.ToString, New Font("Arial", 50, FontStyle.Regular), New SolidBrush(Color.Black), New Point(940, 40), drawformat)

2 个答案:

答案 0 :(得分:0)

一些想法(不知道他们是否满足Sonarqube):

  • 不需要测试bbResponse.getEmails().isEmpty()。空列表上的forEach()完全有效,将执行其主体零次。

  • 正如已经在注释中所写,您可以使用switch语句替换字符串比较条件。

  • 您可以将lambda表达式重构为自己的方法,并在forEach()调用中使用方法引用。

  • 如果帖子中的//CODE块长于几行,则可以将其重构为它们自己的方法。

顺便说一句:

Sonarqube肯定会提供有价值的建议,但我绝不会把它定为硬门。

让自动贩卖机在规则上有些晦涩难懂,以决定可接受的代码样式对我来说似乎不是一个好主意。我们都想要干净的,人类可读的代码,这与Sonarqube兼容的代码不同。

例如Sonarqube无法判断可读性的最重要方面:类,字段,变量等的命名。而您的问题表明,例如复杂度规则会拒绝没有开发人员会认为“难以阅读”的代码(除非您省略的“ CODE”块过长)。

答案 1 :(得分:0)

  1. 如果您使用stream(),则检查非空列表可能是多余的,并且也可以使用forEach而不调用.stream()
  2. 可以为特定代码准备消费者方法图
  3. 从地图中获取可为空的使用者或引发异常时,请使用Optional::ifPresentOrElse
static void handleEmails(List<BBEmail> emails) {

    if (null != emails) {
        Map<String, Consumer<BBEmail>> codes = Map.of(
                "CHK", MyClass::processChkEmail,
                "CHT", MyClass::processChtEmail,
                "MYT", MyClass::processMytEmail
        );
        emails.orEach(bbEmail -> 
                  Optional.ofNullable(codes.get(bbEmail.getSEQ()))
                          .ifPresentOrElse(consumer -> consumer.accept(bbEmail),
                                           () -> {throw new IllegalStateException();}
                          )
              );
    }
}

static void processChkEmail(BBEmail email) {
    // TODO CHK
}

static void processChtEmail(BBEmail email) {
    // TODO CHT
}

static void processMytEmail(BBEmail email) {
    // TODO MYT
}

这应该可以解决声纳问题,但是我不太确定它会提高人类的可读性:)


前面提到的另一个选项是switch语句-如果没有break语句,对于Java 12+语法可以更加简洁:

static void handleEmailSwitchJava12(List<BBEmail> emails) {
    if (null != emails) {
        emails.forEach(bbEmail -> {
            switch (bbEmail.getSEQ()) {
                case "CHK" -> processChkEmail(bbEmail);
                case "CHT" -> processChtEmail(bbEmail); 
                case "MYT" -> processMytEmail(bbEmail);
                default -> throw new IllegalStateException("Invalid SEQ code: " + bbEmail.getSEQ());
            }
        });
    }
}