简体   繁体   English

减少圈复杂度,多个if语句java

[英]Reducing the cyclomatic complexity, multiple if statements java

I have a lot more of these else-if conditions that I have not included. 我还有更多其他的 - 如果我没有包括的条件。 How could I refactor this to reduce the cyclomatic complexity? 我怎么能重构这个以减少圈复杂度呢?

if (ONE.equalsIgnoreCase(eachTag.getNodeName()))
{
    myclassDto.setOne(formatter
            .getElementValueAfterNullCheckWithTrim((Element) eachTag));
}
else if (TWO.equalsIgnoreCase(eachTag.getNodeName()))
{
    myclassDto.setTwo(formatter
            .getElementValueAfterNullCheckWithTrim((Element) eachTag));
}
else if (THREE.equalsIgnoreCase(eachTag.getNodeName()))
{
    myclassDto.setThree(formatter
            .getElementValueAfterNullCheckWithTrim((Element) eachTag));
}
else if (FOUR.equalsIgnoreCase(eachTag.getNodeName()))
{
    myclassDto.setFour(formatter
            .getElementValueAfterNullCheckWithTrim((Element) eachTag));
}
else if (FIVE.equalsIgnoreCase(eachTag.getNodeName()))
{
    myclassDto.setFive(formatter
            .getElementValueAfterNullCheckWithTrim((Element) eachTag));
}
else if (SIX.equalsIgnoreCase(eachTag.getNodeName()))
{
    myclassDto.setSix(formatter
            .getElementValueAfterNullCheckWithTrim((Element) eachTag));
}

How can I reduce the cyclomatic complexity of this function in java? 如何在java中减少此函数的圈复杂度?

Your code would be easier to read, while it's just as "complex" (while it's not really that complex), if you: 您的代码将更容易阅读,而它就像“复杂”(虽然它并不是那么复杂),如果您:

  • Use a switch statement 使用switch语句
  • Extract the value of getNodeName() beforehand 事先提取getNodeName()的值
  • Extract the value returned by getElementValueAfterNullCheckWithTrim() beforehand 事先提取getElementValueAfterNullCheckWithTrim()返回的值

     String value = formatter.getElementValueAfterNullCheckWithTrim((Element) eachTag); String nodeName = eachTag.getNodeName(); switch (nodeName) { case ONE: myclassDto.setOne(value); break; case TWO: myclassDto.setTwo(value); break; ... } 

Edit: You might want to refactor your DTO so it's easier to use, like 编辑:您可能想要重构您的DTO,以便更容易使用,例如

  myclassDto.setValue(nodeName, value)

I'd define a mapping of Strings to the functions they correspond with. 我将字符串映射到它们对应的函数。 This can be static. 这可以是静态的。

Then you can loop over the mappings, find the appropriate one ( filter ) and apply the function. 然后,您可以循环遍历映射,找到合适的映射( filter )并应用该函数。

private static final Map<String, BiConsumer<MyClassDto, Element>> MAPPING = new HashMap();

static
{
    mapping.put(ONE, MyClassDto::setOne);
    mapping.put(TWO, MyClassDto::setTwo);
    //...
    mapping.put(SIX, MyClassDto::setSix);
}


//...

MAPPING.entrySet().stream()
    .filter(pair -> pair.getKey().equalsIgnoreCase(eachTag.getNodeName()))
    .map(Map.Entry::getValue)
    .forEach(func -> func.accept(
        myClassDto,
        formatter.getElementValueAfterNullCheckWithTrim((Element) eachTag)
    ));

You may want to consider the case where MAPPING can contain different keys which are treated equally by equalsIgnoreCase (eg "AAA" and "aaa"). 您可能需要考虑MAPPING可以包含由equalsIgnoreCase (例如“AAA”和“aaa”)平等对待的不同键的情况。

One solution is to use findFirst().ifPresent() in place of forEach (as suggested by daniu ) but this may mask some error cases so use it with caution. 一种解决方案是使用findFirst().ifPresent()代替forEach (由daniu建议)但这可能会掩盖一些错误情况,因此请谨慎使用它。

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

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