如何用很多if构造重构一个大函数?

时间:2012-03-29 11:08:23

标签: java if-statement refactoring dry

我们将App A作为主要应用。现在我们从App B构建,它使用App A的一部分功能。

应用程序A保持不变,而应用程序B仅使用A

的子集

因此,我希望在没有或尽可能少的出版物的情况下重构函数,并且具有最大的可读性。

所以函数看起来像这样(它实际上更长,这是摘录):

  class SomeClass {

    Data prepareData() {

     if (this.bothId==1 || this.appAid=2 /*or only relevant for appA*/) {       
        if(this.data==null) { /*appA*/
            appAdoSmth(); /*appA*/
        }
        boolean merge=false; /*appA*/
        if (this.data==null) { /*appA*/
          merge=appAanalyze(data); /*appA*/
        }
        bothPrepare(merge); 
    } else if (bothIsRelevant()) {
      if(appArelevant()) { /*appA*/
        data=appAprepare(); /*appA*/
      } else {
        data=prepareBoth(); 
      }     
      bothUpdateSomeValue();
    }

  }

你会怎么做?

4 个答案:

答案 0 :(得分:2)

其他答案解决了如何重构代码的一般问题。他们提供了很好的建议,但我认为这不是你所要求的。

我认为您在询问问题中是否可能重构代码。

很难给出一般适用的答案,甚至是特别适用的答案。 (示例代码不是您的真实代码,并且有点难以理解它实际上“意味着什么”)。

  • AndreasD给出了一种方法:将大型复杂的嵌套if分解为单独的方法。

  • 另一种方法是使用Stragegy设计模式。将特定于每个应用程序的代码分隔为策略类。例如:

    interface Strategy {
        Data prepareData();
    }
    
    class GeneralStrategy implements Strategy {
        Data prepareData() {
            // do general preparation
        }
    }
    
    class App1Strategy extends GeneralStrategy {
        Data prepareData() {
            // do app1-specific preparation
            super.prepareData();
            // do more app1-specific preparation
        }
    }
    

等等。

答案 1 :(得分:1)

我理想的世界开发单元测试,验证您的功能的现有实现是否有效。

然后开始逐步更改代码并在每次更改后运行测试。 在不知道您的代码结构的情况下很难给出正式的建议。但通常会尝试查找重复的代码片段,编写使用参数实现此逻辑的方法,并将重复的片段替换为新方法。等等等。

祝你好运。

答案 2 :(得分:0)

如果我是你,我会在这堂课上报道一份报道。 (例如http://ecobertura.johoop.de/http://www.eclemma.org/)这样,Eclipse可以显示绿色的覆盖线,这有助于您识别案例。通过这种帮助,可以更容易地分离绿线并将其拉入方法中。

答案 3 :(得分:0)

可以通过在单独的方法中提取某些逻辑来提高可读性。这是一种重构方法。

Data prepareData() {
  if (this.bothId==1 || this.appAid=2 ) {
    handleCase1();  // <- you'll find better names for the methods      
  } else if (bothIsRelevant()) {
    handleCase2();
  }
}

private void handleCase1() {
  if(this.data==null) {
    appAdoSmth(); 
  }
  boolean merge=false; 
  if (this.data==null) { 
    merge=appAanalyze(data); 
  }
  bothPrepare(merge); 
}

private handleCase2() {
  if(appArelevant()) { 
    data=appAprepare(); 
  } else {
    data=prepareBoth(); 
  }     
  bothUpdateSomeValue();
}

当然,这并没有减少if / else的数量,但它使“主”方法变得简单。