这种方法“setHeader”的Cyclomatic Complexity是139,大于10授权

时间:2018-04-27 09:41:50

标签: java-8 sonarqube

我在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;

    }
}

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

2 个答案:

答案 0 :(得分:4)

<> Eugene的答案非常好,但您可以更进一步,在枚举中使用相同的逻辑

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

答案 1 :(得分:2)

首先有一点背景知识:

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

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

无论如何,执行String切换实际上是一个O(1)的查找切换(即使执行其中两个)。

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

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