Java 使用返回语句重构代码

Java 使用返回语句重构代码,java,refactoring,Java,Refactoring,带有checkcustomers的“if”块正好用于该类中的其他方法,因此对于相同的检查有很多代码重复应用。但是我也不能直接将这个checksomethings提取到一个方法中,因为它们有返回值 重构此代码的一些好主意?我只是修改了这段代码来简化这里的内容,所以不要在这段代码中发现一些小问题(如果有),基本上问题是当当前方法中有很多返回时,如何将一段代码提取到一个方法(因为它在其他方法上是重复的) public Details getCustomerDetails(){ if(check

带有checkcustomers的“if”块正好用于该类中的其他方法,因此对于相同的检查有很多代码重复应用。但是我也不能直接将这个checksomethings提取到一个方法中,因为它们有返回值

重构此代码的一些好主意?我只是修改了这段代码来简化这里的内容,所以不要在这段代码中发现一些小问题(如果有),基本上问题是当当前方法中有很多返回时,如何将一段代码提取到一个方法(因为它在其他方法上是重复的)

public Details getCustomerDetails(){

   if(checkifcustomerhasnoboobs){    
    ..worry about it..
   return new Details("no");
  }

   if(checkifcustomerplaytenniswell){    
    ..do find a tennis teacher
    return new Details("no cantplay");
  }
  //...ok now if customer passed the test, now do the some real stuff
  //
  //
  CustomerDetails details= getCustomerDetailsFromSomewhere();

  return details;

}
这个怎么样

public Result checkSomethings() {
  if ( checksomething1 ) {
    return ResultCheckSomething1;
  }
  if ( checksomething2 ) {
    return ResultCheckSomething2;
  }
  return ResultCheckNone;
}

public Details getCustomerDetails(){
  Result result = checkSomethings();
  switch ( result ) {
    case ResultCheckSomething1:
      return new Details("message1");
    case ResultCheckSomething2:
      return new Details("message2");
    default:
      return getCustomerDetailsFromSomewhere();
  }
}

结果…
代码将在枚举中。

可能是这样的吗

   public Details getCustomerDetails(){
       boolean isError = checksomething1() || checksomething2();
       String message = checksomething1() ? "message1" : "message2";
       return isError ? new Details(message) : getCustomerDetailsFromSomewhere();
}
如果您尝试两次避免调用检查函数,请保留它的结果

public Details getCustomerDetails(){
   boolean check1 = checksomething1();
   boolean check2 = checksomething2();
   String message = check1 ? "message1" : "message2";
   return (check1 || check2) ? new Details(message) : getCustomerDetailsFromSomewhere();

}

将返回值替换为对结果变量的赋值,该结果变量在第一次赋值之前保持null。如果更改结果的条件为false,则每个块都可以由返回null的函数替换

正如herman在一篇评论中指出的,只有在其中一个调用不可能导致null时,这种方法才有效

public Details getCustomerDetails(){
   Details result = null;

   if(checksomething1){    
    ..error
     result = new Details("message1");
  }

  if(result == null) {
    if(checksomething2){    
    ..error
    result = new Details("message2");
  } 

  if(result == null){

    result = getCustomerDetailsFromSomewhere();
  }

  return result;

}
我会这样做:

public Details getCustomerDetails(){  

  Details invalidDetails = checkForInvalidCustomer();
  if (invalidDetails !=null) {
     return (invalidDetails);
  }

  //...ok now if customer passed the test, now do the some real stuff
  //
  //
  CustomerDetails details= getCustomerDetailsFromSomewhere();
  return details;
}

public Details checkForInvalidCustomer() {
   if(checkifcustomerhasnoboobs){    
    ..worry about it..
    return new Details("no");
   }
   if(checkifcustomerplaytenniswell){    
    ..do find a tennis teacher
    return new Details("no cantplay");
  }
  // nulls means valid customer
  return (null);
}

基本上,对于您的特定示例,我使用null,以便区分没有匹配条件的情况,与任何条件匹配的情况。这样我就可以使用单个if语句。现在,如果您想返回null,您需要稍微修改这个解决方案,也许可以使用一些常量来标记案例,而不是使用null。

使用Java 8,您可以重构为一个返回
可选值的方法。
像
这样的语句返回x
将替换为
返回可选。of(x)
(假设x不能为空)。末尾的默认return语句是
returnoptional.empty()


然后,您可以使用
return optional.orElseGet(()->…)
来计算不会达到原始返回语句的情况下的值。

您的意思是重复“checksomething”吗?如果是这样的话,这些就是业务规则,这意味着您可以将它们提取到一个方法中,只需从不同的位置调用该方法即可。您可以有一个返回详细信息对象的泛型validate()方法。您可以说,如果它返回null,则一切正常,否则在调用方法中返回Details对象。我想在本例中,您将拥有一个带有
getDetails()
的接口,每个场景都有一个实现(在本例中,有两个实现:error1和error2)。然后是一个包含这些实现的地图,其中键是您在checksomething中使用的内容,值是实现。@cklab tnxQ@Spring我不明白为什么你不能提取这个仅仅因为它有返回值。如果它不符合这些
If
s中的任何一个,则可以从提取的方法返回null,表示客户通过了测试。这里很难推荐“最佳实践”,因为我们只接触到代码的一小部分。我不知道所有这些对象是如何相互作用的。我的意思是“enum Result{resultchecksomething 1,resultchecksomething 2}”或类似的东西来定义返回值。sry我不明白你到底想做什么:)我会尽量避免调用checksomething 1()两次。只有当要提取的代码中的return语句不能返回null时,这才可能。