Java 代码中还有许多if语句

Java 代码中还有许多if语句,java,if-statement,conditional,sentence,Java,If Statement,Conditional,Sentence,我想问一下,如果有许多其他基于如下布尔条件的if语句,这是否是一种好方法 public void borrowItem() throws IOException { boolean ableToBorrow = isUserAbleToBorrow(cardID); boolean isDemand = checkDemand(title, authorNumber); boolean userExists = checkIfUserExists(cardID);

我想问一下,如果有许多其他基于如下布尔条件的if语句,这是否是一种好方法

public void borrowItem() throws IOException {

    boolean ableToBorrow = isUserAbleToBorrow(cardID);
    boolean isDemand = checkDemand(title, authorNumber);
    boolean userExists = checkIfUserExists(cardID);


    if(ableToBorrow && isDemand && userExists) {

           //lots of code....

    }else if(!ableToBorrow && isDemand && userExists) {
        System.out.println("User limit  exceeded");
    }else if(!ableToBorrow && !isDemand && userExists) {
        System.out.println("User limit  exceeded and no book demand");
    }else if(ableToBorrow && !isDemand && userExists) {
        System.out.println("No book demand");
    }else if(ableToBorrow && !isDemand && !userExists) {
        System.out.println("No book demand and user does not exists");
    }else if(ableToBorrow && isDemand && !userExists) {
        System.out.println("Unrecognized user!");
    }

}

这是一种好方法还是java中有更好的方法来做到这一点?

这是一种非常糟糕的风格:难以阅读和理解,当你被要求改进/改变行为时,很容易搞砸。请注意,这样的代码也非常难测试,因为您希望确保覆盖流在这种方法中可能采取的所有路径

这类问题的典型答案是使用多态性,比如有一个定义某些接口的基类,以及每个实现接口的特定子类


从这个意义上说:您的代码显然违反了:您的代码从某处查询某些状态,然后对此做出决定。相反,您可以创建类/对象,并告诉它们做正确的事情(同样,这就是多态性的作用所在)。

这种方式没有问题,但是如果您希望代码更简洁,还有其他选择。如果我稍微更改您的错误消息,我可以这样写:

if(ableToBorrow && isDemand && userExists) {
   //lots of code....
} else {
  String errorMsg = "";
  if (!ableToBorrow) errorMsg += "User limit  exceeded - ";
  if (!isDemand) errorMsg += "No book demand - ";
  if (!userExists) errorMsg += "Unrecognized user!"
  System.out.println(errorMsg);
} 
还可以选择将布尔值绑定到单个整数值中。但是,这混淆了代码的作用,我个人不会使用它,除非您想创建一个枚举来跟踪整数值的含义

int status = 4*(ableToBorrow?1:0)+2*(isDemand?1:0)+(userExists?1:0);
switch(status){
  case 7:  //lots of code....
    break;
  case 3:  System.out.println("User limit  exceeded");
    break;
  //etc...
}
我同意你所说的。这太程序化了。实现多态性的一种方法(可能是本例中最好的方法)是

定义您的界面:

public interface User {
    void borrowItem(String item);
    String cardId();
}
创建基本实现:

public final class SimpleUser implements User {
    private final String cardId;
    public SimpleUser(final String cardId) {
        this.cardId = cardId;
    }
    @Override
    public void borrowItem(final String item) {
        // Borrowing logic.
    }
    @Override
    public String cardId() {
        return cardId;
    }
}
然后为您需要的每个验证添加装饰器。例如,要检查用户是否存在:

public final class ExistingUser implements User {
    private final User origin;
    public ExistingUser(final User origin) {
        this.origin = origin;
    }
    @Override
    public void borrowItem(final String item) {
        if (!exists(cardId())) {
            throw new IllegalStateException("Unrecognized user!");
        }
        origin.borrowItem(item);
    }
    @Override
    public String cardId() {
        return origin.cardId();
    }
    private boolean exists(String cardId) {
        // Check if exists...
    }
}
并将它们结合起来。这样,当您需要一个额外的验证时,您可以添加一个额外的装饰器。使用
if
s,病例数将以几何级数增长

new ExistingUser(
    new DemandAwareUser(
        new SafelyBorrowingUser(
            new SimpleUser(cardId)
        )
    )
).borrowItem(item);

“好”是什么?只要你的代码是可读的,那么多个if-else就没有问题。你可以用分层的方式对它进行分段,比如
if(ableToBorrow)
和它内部的
if(isDemand)
和它内部的
if(userExists)
。也许有一个更好的方法,我现在还没有看到。不,不好。很难阅读代码,也很难理解每个条件的作用,以及是否涵盖了所有可能的真/假组合。@Maroun啊,不。不。简单地说不。如果其他条件不变,那么长链(几乎)永远都不是一件好事。你尽可能避免它们。@GhostCat,除非你是研究人员;)说真的,有时候过度OOP会导致糟糕的代码。如果它是一堆4-5个If-else,我可以很容易地接受它。
int status
在C/驱动程序代码中是(将是)很好的技巧,但在这里很难接受,我将尝试,谢谢:)