java if else 重构
java Refactoring if else
我有这个 if else 代码,我想知道是否有更多 useful/intelligent 的编写方式:
public void saveContent() throws Exception {
if(book.isColored()) {
book.setChoosen(“1234”);
} else if (book.isAvailable()) {
book.setChosen(“23498”);
} else if (book.isAdults()) {
book.setChosen(“0562”);
} else {
ReaderResponse response = reader.getReaderResponse();
if (response != null) {
book.setChosen(response.getName());
}
} else {
book.setChosen(“4587”);
}
}
}
方法returns无效。
Switch 语句无济于事,因为您正在检查不同种类的属性。我会使用 if statements
但我会使用一些 static final
常量而不是 "magical numbers"。我会将最后一个 else
语句的内部删除到一个单独的方法中。
这中间引入一个局部变量就出问题了。解决这个问题的一种方法是引入另一种方法 - 不要害怕小方法。
public void saveContent() throws Exception {
book.setChoosen(
book.isColored() ? “1234" :
book.isAvailable() ? “23498” :
book.isAdults() ? “0562” :
readerResponse()
);
}
private String readerResponse() throws Exception {
ReaderResponse response = reader.getReaderResponse();
return response == null ? “4587” : response.getName();
}
?
:
是条件运算符,常被称为三元运算符。
如果getReaderResponse
没有副作用,您可以重复调用。 get
方法 通常 没有副作用,但我觉得这里可能会有副作用。我不确定 Exception
抛出的位置 - 我假设它打算用子类型替换。
您可以实施策略设计模式来替代 if-else 构造
好吧,这是我考虑了几个月的问题。在我看来,对于非高级程序员来说,以一种聪明且可重复的方式编写代码并不容易。一个好方法是使用 switch 语句,但这不适用于布尔语句。
我会使用问题中提到的代码,但我会将其移至单个 class/controller/service 以获得更复杂的代码(这对于测试复杂行为会更好)。
我不会说这是更有效、更有用或更聪明的方法,但我当然认为通过将实际选择的代码解析委托给不同的方法,代码将更清晰和可测试:
public void saveContent() throws Exception {
String choosenCode = getChoosenCode(book);
book.setChoosen(choosenCode);
}
static String getChoosenCode(Book book) throws Exception {
if (book.isColored()) {
return “1234”;
}
if (book.isAvailable()) {
return “23498”;
}
if (book.isAdults()) {
return “0562”;
}
ReaderResponse response = reader.getReaderResponse();
return (response != null)
? response.getName()
: “4587”;
}
如您所见,由于早期的 return 方法,不需要无穷无尽的 if-else 块。这也提供了对所选代码部分进行单元测试的能力,如果您有 void
returning 方法,这会稍微复杂一些。
只是想添加一个 Stream 版本,但我认为它不足以满足少数情况。
List<Pair<Predicate<Book>, String>> mapping;
mapping.add(Book::isColored, "1234");
mapping.add(Book::isAvailable, "23498");
mapping.add(Book::isAdults, "0562");
ReaderResponse response = reader.getReaderResponse();
mapping.add((anyBook) -> response == null, "4587");
String chosen = mapping.stream()
.filter(p -> p.getKey().test(book))
.map(Pair::getValue)
.findFirst()
.orElseGet(response::getName);
或者
mapping.add((anyBook) -> true, response.getName());
mapping.stream()
.filter(p -> p.getKey().test(book))
.map(Pair::getValue)
.findFirst()
.ifPresent(book::setChose);
这并没有完全实现你的算法(因为有一些歧义)但是演示了使用enum
作为策略模式。在这种形式中,add/adjust 代码更容易,因为每种书籍类型的所有特殊功能都在它自己的位置(它自己的 enum
)。
请注意,当一本书可以分为多种类型时(例如 Coloured
和 Adult
),这也会有所帮助。
enum BookType {
Coloured("1234"),
Available("23498"),
Adult("0562");
private final String chosen;
BookType(String chosen) {
this.chosen = chosen;
}
public String getChosen() {
return chosen;
}
}
class Book {
final Set<BookType> types = EnumSet.noneOf(BookType.class);
Book book;
public boolean hasType(BookType type) {
return types.contains(type);
}
public void setChosen(String s) {
}
}
public void saveContent() throws Exception {
for(BookType type: BookType.values()) {
if(book.hasType(type)) {
book.setChosen(type.getChosen());
}
}
}
我有这个 if else 代码,我想知道是否有更多 useful/intelligent 的编写方式:
public void saveContent() throws Exception {
if(book.isColored()) {
book.setChoosen(“1234”);
} else if (book.isAvailable()) {
book.setChosen(“23498”);
} else if (book.isAdults()) {
book.setChosen(“0562”);
} else {
ReaderResponse response = reader.getReaderResponse();
if (response != null) {
book.setChosen(response.getName());
}
} else {
book.setChosen(“4587”);
}
}
}
方法returns无效。
Switch 语句无济于事,因为您正在检查不同种类的属性。我会使用 if statements
但我会使用一些 static final
常量而不是 "magical numbers"。我会将最后一个 else
语句的内部删除到一个单独的方法中。
这中间引入一个局部变量就出问题了。解决这个问题的一种方法是引入另一种方法 - 不要害怕小方法。
public void saveContent() throws Exception {
book.setChoosen(
book.isColored() ? “1234" :
book.isAvailable() ? “23498” :
book.isAdults() ? “0562” :
readerResponse()
);
}
private String readerResponse() throws Exception {
ReaderResponse response = reader.getReaderResponse();
return response == null ? “4587” : response.getName();
}
?
:
是条件运算符,常被称为三元运算符。
如果getReaderResponse
没有副作用,您可以重复调用。 get
方法 通常 没有副作用,但我觉得这里可能会有副作用。我不确定 Exception
抛出的位置 - 我假设它打算用子类型替换。
您可以实施策略设计模式来替代 if-else 构造
好吧,这是我考虑了几个月的问题。在我看来,对于非高级程序员来说,以一种聪明且可重复的方式编写代码并不容易。一个好方法是使用 switch 语句,但这不适用于布尔语句。
我会使用问题中提到的代码,但我会将其移至单个 class/controller/service 以获得更复杂的代码(这对于测试复杂行为会更好)。
我不会说这是更有效、更有用或更聪明的方法,但我当然认为通过将实际选择的代码解析委托给不同的方法,代码将更清晰和可测试:
public void saveContent() throws Exception {
String choosenCode = getChoosenCode(book);
book.setChoosen(choosenCode);
}
static String getChoosenCode(Book book) throws Exception {
if (book.isColored()) {
return “1234”;
}
if (book.isAvailable()) {
return “23498”;
}
if (book.isAdults()) {
return “0562”;
}
ReaderResponse response = reader.getReaderResponse();
return (response != null)
? response.getName()
: “4587”;
}
如您所见,由于早期的 return 方法,不需要无穷无尽的 if-else 块。这也提供了对所选代码部分进行单元测试的能力,如果您有 void
returning 方法,这会稍微复杂一些。
只是想添加一个 Stream 版本,但我认为它不足以满足少数情况。
List<Pair<Predicate<Book>, String>> mapping;
mapping.add(Book::isColored, "1234");
mapping.add(Book::isAvailable, "23498");
mapping.add(Book::isAdults, "0562");
ReaderResponse response = reader.getReaderResponse();
mapping.add((anyBook) -> response == null, "4587");
String chosen = mapping.stream()
.filter(p -> p.getKey().test(book))
.map(Pair::getValue)
.findFirst()
.orElseGet(response::getName);
或者
mapping.add((anyBook) -> true, response.getName());
mapping.stream()
.filter(p -> p.getKey().test(book))
.map(Pair::getValue)
.findFirst()
.ifPresent(book::setChose);
这并没有完全实现你的算法(因为有一些歧义)但是演示了使用enum
作为策略模式。在这种形式中,add/adjust 代码更容易,因为每种书籍类型的所有特殊功能都在它自己的位置(它自己的 enum
)。
请注意,当一本书可以分为多种类型时(例如 Coloured
和 Adult
),这也会有所帮助。
enum BookType {
Coloured("1234"),
Available("23498"),
Adult("0562");
private final String chosen;
BookType(String chosen) {
this.chosen = chosen;
}
public String getChosen() {
return chosen;
}
}
class Book {
final Set<BookType> types = EnumSet.noneOf(BookType.class);
Book book;
public boolean hasType(BookType type) {
return types.contains(type);
}
public void setChosen(String s) {
}
}
public void saveContent() throws Exception {
for(BookType type: BookType.values()) {
if(book.hasType(type)) {
book.setChosen(type.getChosen());
}
}
}