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

时间:2017-12-20 12:20:35

标签: java complexity-theory reduce

我还有更多这些其他的 - 如果我没有包括的条件。我怎么能重构这个以减少圈复杂度?

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

如何在java中减少此函数的圈复杂度?

2 个答案:

答案 0 :(得分:2)

你的代码会更容易阅读,而它就像“复杂”一样(虽然它并不那么复杂),如果你:

  • 使用开关声明
  • 预先提取getNodeName()的值
  • 事先提取getElementValueAfterNullCheckWithTrim()返回的值

    import matplotlib.pyplot as plt
    
    background = 0
    if background == 0:
      back_color='black'
      fore_color='white'
    else:
      back_color='white'
      fore_color='black'
    fig, ax = plt.subplots()
    fig.patch.set_facecolor(back_color)
    im = ax.imshow([[1e5,2e5],[0.1e5,1e5]])
    ax.axis( 'off' )  # don't show the axes ticks/lines/etc. associated with the image
    cb = plt.colorbar(im)
    cb.formatter.set_scientific(True)
    cb.formatter.set_powerlimits((0,0))
    cbytick_obj = plt.getp(cb.ax, 'yticklabels' ) #Set y tick label color
    plt.setp(cbytick_obj, color=fore_color)
    cb.ax.tick_params(which = 'minor', length = 2, color = fore_color )
    cb.ax.tick_params(which = 'major', length = 4, color = fore_color )
    cb.ax.minorticks_on()
    cb.update_ticks()
    plt.show()
    

编辑: 您可能想要重构您的DTO,以便更容易使用,例如

String value = formatter.getElementValueAfterNullCheckWithTrim((Element) eachTag);
String nodeName = eachTag.getNodeName();

switch (nodeName) {
    case ONE:
        myclassDto.setOne(value);
        break;
    case TWO:
        myclassDto.setTwo(value);
        break;
    ...
}

答案 1 :(得分:1)

我定义了字符串到它们对应的函数的映射。这可能是静态的。

然后你可以遍历映射,找到合适的映射(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)
    ));

您可能需要考虑MAPPING可以包含由equalsIgnoreCase平等对待的不同键的情况(例如&#34; AAA&#34;和#34; aaa&#34;)

一种解决方案是使用findFirst().ifPresent()代替forEach(由daniu建议),但这可能会掩盖一些错误情况,因此请谨慎使用。