【问题标题】:The Cyclomatic Complexity of this method "setHeader" is 139 which is greater than 10 authorized此方法“setHeader”的圈复杂度为 139,大于 10 授权
【发布时间】:2018-04-30 03:01:42
【问题描述】:

我在 setHeader 中有 139 个开关案例

private static void setHeader(String headertableField, String headerValue) {
    switch (headertableField) {
        case AUS:
            headerDTO.setAudval(StringUtils.getTrimValueAfterNullCheck(headerValue));
            break;

        case AXL:
            headerDTO.setAxlfieldl(StringUtils.getTrimValueAfterNullCheck(headerValue));
            break;

        ................
        ..................
        default:
            break;

    }
}

它显示声纳问题。您能否提出任何降低复杂性的解决方案。

【问题讨论】:

  • 139 个开关...我只是想象它的样子:|可能是MapMap<Enum, Consumer<HeaderDTO>>?
  • 如此大量的案例可能暗示这 139 种行为应该存在于该类之外的其他地方。使用Map 作为@Eugene 可能会解决SonarQube 问题,但不要将此表面修复作为停止考虑代码改进的许可。
  • @Jubobs 如果 OP 真的有这么多可能性怎么办?我认为任何类型的重构都没有帮助
  • 顺便说一句,您可以在这里接受答案...meta.stackexchange.com/questions/5234/…

标签: java-8 sonarqube


【解决方案1】:

Eugene 的回答很不错,但你可以更进一步,在 enum 中使用相同的逻辑

enum HeaderField {
    AUS(HeaderDTO::setAudval),
    AXL(HeaderDTO::setAxlfieldl);

    private BiConsumer<HeaderDTO, String> fieldSetter;

    HeaderField(BiConsumer<HeaderDTO, String> setter) {
        fieldSetter= setter;
    }

    public void setField(HeaderDTO headerDTO, String value) {
        fieldSetter.accept(headerDTO, value);
    }
}

然后就可以使用了:

HeaderField.AUS.setField(headerDTO, "value");
HeaderField.AXL.setField(headerDTO, "axl");

【讨论】:

    【解决方案2】:

    先介绍一点背景:

    当您将case/switchString 一起使用时,这不是一个简单的 if/else/equals 检查。在内部(例如与 int 类型不同),首先在您打开的字符串上计算 hashCode 并在其上调用 lookupswitch

    如果此 hashCode 值等于 case 语句中存在的值之一(这意味着此字符串可能等于您要查找的值),请在预定义的值上执行另一个 lookupswitch,该值取决于你从哪里“来”(之前的lookupswitch告诉你从哪里跳)。

    不管怎样,做String switch其实就是一个lookupswitch,也就是O(1)(就算做了两个)。

    您可以做的是,通过MapO(1) 的相同价格隐藏这种复杂性。

    Map<String, BiConsumer<HeaderDTO, String>> MAP = Map.of(
          "AUS", (x, y) -> x.setAudval(StringUtils.getTrimValueAfterNullCheck(y))
          // all other cases
    )
    

    然后简单地让这张地图做一个:

    private static void setHeader(String headertableField, String headerValue){
        MAP.get(headertableField).accept(headerDTO, headerValue);
    }
    

    【讨论】:

      猜你喜欢
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 2013-12-27
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 2015-09-11
      • 1970-01-01
      相关资源
      最近更新 更多