【问题标题】:Simplifying an if (do some operation) then return [closed]简化if(做一些操作)然后返回[关闭]
【发布时间】:2015-12-18 03:52:56
【问题描述】:

这可能很常见,可能是一个愚蠢的问题,但我真的很想知道其他人如何处理这个问题。

说我有:

private void actionPerformed(ActionEvent evt){
     String text = textfield.getText();
     if(isValid(text)){
         // do something eg:
         list.add(text);
     }
}

private boolean isValid(String text){
    if(text.isEmpty()){
      displayErrorMessage("empty string!");
      return false;
    }
    if(hasInvalidChars(text)){
      displayErrorMessage("Invalid chars");
      return false;
    }
    ....
    return true;
}

isValid(String) 方法感觉怪怪的,我认为一个方法应该只做一件简单的事情,但是 isValid() 肯定违反了它,它显示一个错误消息然后返回一个布尔值。

这样好吗?还是有其他方法可以绕过它?

我能想到的另一个不太优雅的解决方法是实现一个标志。即:

private void actionPerformed(ActionEvent evt){
       String text = textfield.getText();
       verify(text);

       if(!errorIsDisplayed){
          list.add(text);
       }   
}

private boolean verify(String text){
    if(text.isEmpty()){
      displayErrorMessage("empty string!");
      errorIsDisplayed = true;
    }
    if(hasInvalidChars(text)){
      displayErrorMessage("Invalid chars");
      errorIsDisplayed = true;
    }
    ....
    errorIsDisplayed = false;
}

我希望你能清楚地看到我试图解决的问题,我认为我缺少一个简单的解决方案,可能是由于睡眠不足和天气原因,我不知道。其他人将如何实现这一点?

【问题讨论】:

  • 您可以根据 isValid 返回的内容在外部显示它们,而不是在方法内部显示消息,但是您将无法在其中区分两种情况。除了感觉怪异之外,您目前拥有的还有其他问题吗?
  • 是的,这就是我当前的行动点,将 isValid() 的实现移动到 actionPerformed() 本身中。我只是觉得 actionPerformed() 会混乱。我认为拥有像 isValid() 这样的方法会以某种方式使代码在显示意图时更具可读性。

标签: java if-statement coding-style refactoring code-cleanup


【解决方案1】:

如果你喜欢,
你可以定义一个错误类型的enum,而isValid方法只返回类型。

enum Type{
    VALID("Valid"),
    EMPTY("Empty String"),
    // other types.

    public final String message;
}

对于某个文本字符串,可以定义一个方法getType来获取其对应的Type。

Type getType(String text){...}

那么你的isValid 方法应该只检查这条消息是否有效。

boolean isValid(Type type){
    return type == Type.VALID;
}

而在actionPerformed 中,您可以根据文本字符串的类型采取行动。

actionPerformed(...){
    String text = ...
    Type type = getType(text);
    if (isValid(type)){
        //Actions for valid text
    } else {
        //Actions for invalid text
        System.out.println(type.message);
    }
}

【讨论】:

  • 这是一个很好的观点,但我认为它不能满足我的具体问题。我想将所有无效操作移到一个单独的块上,这样我就可以在一个简单的块上处理有效的操作,远离无效的逻辑。
  • 如果我会采用 Type isValid() 的枚举,那么它与直接在 actionPerformed() 中执行整个 if then else of invalids 并没有什么不同,那么最后的 else 子句将用于有效的陈述,类似的东西。另一个不太优雅的解决方案是引入一个标志,一个标志与显示消息一起切换,那么就不需要返回 isValid() 并检查是否设置了标志。
  • 不同意。您可以通过另一种方法获取此消息的类型,例如 getType(arg:String):Type 并将 isValid(arg:String) 更改为 isValid(arg:Type):boolean 并且此 isValid 将仅检查此消息是否有效。如果没有,您可以打印该消息。从逻辑上讲,我认为你不能省略所有的 if 语句。我认为这个解决方案将比你原来的解决方案更具可读性。顺便说一句,感谢您的反馈。 :)
  • Eh...你可以认为这个枚举类是你的flag,但我认为它更像object-oriented
  • 我认为在您的“标志”解决方案中,您的方法与全局变量 errorIsDisplayed 紧密耦合。所以它并不优雅。我确实认为在返回值上交互的两个方法比依赖于方法范围之外的一些变量更优雅。
【解决方案2】:

如果你真的想要,将List<String> unacceptableReasons 的参数传递给isValid() 并将错误消息添加到其中。并继续返回布尔值。 actionPerformed()可以承担显示消息的责任。

errorIsDisplayed 字段的解决方案更难理解,弥补了 IMO 可读性较差的代码。

【讨论】:

  • 是的,我同意你所说的一切,标志不是解决方案,我只是把它放在那里说明重点,或者进一步说明我的问题。我也想避免这一切,你有什么建议?
  • 见我回答的第一段。
猜你喜欢
  • 1970-01-01
  • 2017-07-01
  • 2015-09-29
  • 2012-04-21
  • 2022-10-25
  • 1970-01-01
  • 1970-01-01
  • 2015-09-04
  • 1970-01-01
相关资源
最近更新 更多