代码中的许多其他 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...
}
}
并将它们结合起来。这样,当您需要一个额外的验证时,您可以添加一个额外的装饰器。有了if
s,病例数就会呈几何级数增长。
new ExistingUser(
new DemandAwareUser(
new SafelyBorrowingUser(
new SimpleUser(cardId)
)
)
).borrowItem(item);
我想问一下,如果有很多其他的基于布尔条件的语句是否是一个好方法,如下所示?
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...
}
我同意
定义您的界面:
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);