代码中的许多其他 if 语句

Many else if statements in the code

我想问一下,如果有很多其他的基于布尔条件的语句是否是一个好方法,如下所示?

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 中有更好的主意?

这是非常糟糕的风格:难以阅读和理解,当你被要求 enhance/change 行为时很容易搞砸。请注意,这样的代码也非常难以测试——因为你会想要确保涵盖所有 流程可以采用的可能路径一个方法。

这类事情的典型答案是使用多态性,比如让一个基class定义一些接口,每个子class实现界面不同。

从这个意义上说:您的代码明显违反了 Tell Don't Ask:您编写代码 查询 来自某处的某些状态,然后据此做出决定。相反,您创建 classes/objects 并 告诉 他们做正确的事(再次强调:这就是多态性发挥作用的地方)。

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

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...
}

我同意. It's way too procedural. One way (probably the best way in this case) to implement polymorphism would be the decorator pattern

定义您的界面:

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...
    }
}

并将它们结合起来。这样,当您需要一个额外的验证时,您可以添加一个额外的装饰器。有了ifs,病例数就会呈几何级数增长。

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