【问题标题】:refactoring nested if statements重构嵌套的 if 语句
【发布时间】:2020-01-02 01:55:29
【问题描述】:

我正在尝试重构一些类似于下面代码的代码。我觉得应该有一种更简单的方法来完成它的工作。我主要关心的是在 (!dataA.isEmpty()) 条件的 if 和 else 块中调用 getDataB()。

    DataA dataA = getDataA();

    if (!dataA.isEmpty()) {

        if (dataA.getStatus() == Status.FINAL) {
            // process finalized dataA
        }

        if (dataA.getStatus() == Status.RECEIVED) {
            DataB dataB = getDataB();
            if (!dataB.isEmpty()) {
                dataA.setStatus(dataB.getStatus());
                // process dataA with updated status from dataB
            }
        }

        if (dataA.getStatus() == STATUS.IN_PROGRESS) {
            // process in progress dataA
        }

    // empty dataA
    } else {
        Datab dataB = getDataB();
        if (!dataB.isEmpty()) {
            // process dataB
        }
    }

【问题讨论】:

  • 作为旁注,在你的if 语句中StatusSTATUS 应该有一个一致的大小写。

标签: java if-statement nested refactoring


【解决方案1】:

您可以将重复的逻辑移至接受 lambda 的方法:

void processDataB(Consumer<DataB> action) {
    DataB dataB = getDataB();
    if (!dataB.isEmpty()) {
        action.accept(dataB);
    }
}

然后这样称呼它:

//...
    if (dataA.getStatus() == Status.RECEIVED) {
        processDataB(dataB -> {
            dataA.setStatus(dataB.getStatus());
            // process dataA with updated status from dataB
        });
    }
//...
} else {
    processDataB(dataB ->
        // process dataB
    });
}

【讨论】:

    【解决方案2】:

    仍有改进的空间,但作为初始重构,您可以执行以下操作:

    // I like to get rid of the negations, assuming that DataA and DataB are your objects.
    // I would normally declare a method with more meaning, like hasData(), otherwise just use the negation and the isEmpty.
    
    DataA dataA = getDataA();
    DataB dataB = getDataB();
    
    // When DataA has data
    if (dataA.hasData()) {  
        Status statusA = dataA.getStatus(); 
    
        switch(statusA) {
            case Status.FINAL:
                // process finalized dataA
                break;
            case Status.RECEIVED:
                if (dataB.hasData()) {
                    dataA.setStatus(dataB.getStatus());
                    // process dataA with updated status from dataB
                }
                break; // If you want to process dataA in progress after setting the dataB status in A, then remove this break.
            case Status.IN_PROGRESS:
                // process in progress dataA
                break;          
        }
    
    // When DataB has data
    } else if (dataB.hasData()) {
        // process dataB
    }
    

    【讨论】:

      【解决方案3】:

      首先,在自己的函数中处理dataB(出现在代码的底部),例如:

      private void processDataB() {
          DataB dataB = getDataB();
          if (dataB.isEmpty()) return;
          // process dataB
      }
      

      请注意,如果 dataB 为空,我们如何反转 if 条件以从方法返回。

      接下来,将if 的相同反转应用于主代码。新代码如下所示:

      DataA dataA = getDataA();
      if (dataA.isEmpty()) { //Inverted the test.
          processDataB();
          return;
      }
      
      if (dataA.getStatus() == Status.FINAL) {
          // process finalized dataA
      }
      
      if (dataA.getStatus() == Status.RECEIVED) {
          DataB dataB = getDataB();
          if (!dataB.isEmpty()) {
              dataA.setStatus(dataB.getStatus());
              // process dataA with updated status from dataB
          }
      }
      
      if (dataA.getStatus() == STATUS.IN_PROGRESS) {
          // process in progress dataA
      }
      

      【讨论】:

        猜你喜欢
        • 2015-11-13
        • 2011-02-01
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 2012-06-01
        • 1970-01-01
        相关资源
        最近更新 更多