第九章详细阐述了一系列简化条件表达式的重构手法,旨在提高代码的可读性和可维护性。以下是第九章中列举的一些简化条件表达式的重构手法,通过通俗易懂的语言和具体示例来进一步解释:
分解条件表达式(Decompose Conditional): 当一个复杂的条件表达式难以理解时,将其分解为若干个小条件,使每个条件表达式的意图更加明确。
// Before
if (isSummer() && (temperature > 30)) {
// do something
}
// After
if (isSummer()) {
if (temperature > 30) {
// do something
}
}
合并条件表达式(Consolidate Conditional Expression): 多个条件表达式执行相同的操作时,将这些条件表达式合并为一个条件表达式,使得代码更加简洁。
// Before
if (isWeekend()) {
doSomething();
}
if (isWeekday()) {
doSomething();
}
// After
if (isWeekend() || isWeekday()) {
doSomething();
}
以卫语句取代嵌套条件表达式(Replace Nested Conditional with Guard Clauses): 当使用嵌套的条件表达式难以阅读时,使用卫语句替代,提高代码的清晰度。
// Before
double getPayAmount() {
if (isDead) {
return deadAmount();
} else {
if (isSeparated) {
return separatedAmount();
} else {
if (isRetired) {
return retiredAmount();
} else {
return normalPayAmount();
}
}
}
}
// After
double getPayAmount() {
if (isDead) return deadAmount();
if (isSeparated) return separatedAmount();
if (isRetired) return retiredAmount();
return normalPayAmount();
}
以条件表达式取代卫语句(Replace Guard Clauses with Conditional Expression): 过多的卫语句导致代码重复时,将卫语句合并为一个条件表达式,使得代码更加简洁。
// Before
double getPayAmount() {
if (isDead) {
return deadAmount();
} else {
if (isSeparated) {
return separatedAmount();
} else {
if (isRetired) {
return retiredAmount();
} else {
return normalPayAmount();
}
}
}
}
// After
double getPayAmount() {
return (isDead) ? deadAmount()
: (isSeparated) ? separatedAmount()
: (isRetired) ? retiredAmount()
: normalPayAmount();
}
引入特例(Introduce Special Case): 使用大量的条件判断来处理特殊情况时,引入特例对象,将特殊情况的处理逻辑封装在特例对象中,使得代码更简单。
// Before
double getPayAmount(Employee employee) {
if (employee.isRetired()) {
return employee.getRetiredAmount();
} else {
return employee.getNormalPayAmount();
}
}
// After
double getPayAmount(Employee employee) {
return employee.getPayAmount();
}
移除控制标记(Remove Control Flag): 使用控制标记来控制程序流程时,将控制标记替换为更加清晰的控制结构,使得代码逻辑更容易理解。
// Before
void checkSecurity(String[] people) {
boolean found = false;
for (String person : people) {
if (!found) {
if (person.equals("Don")) {
sendAlert();
found = true;
}
if (person.equals("John")) {
sendAlert();
found = true;
}
}
}
}
// After
void checkSecurity(String[] people) {
for (String person : people) {
if (person.equals("Don") || person.equals("John")) {
sendAlert();
break;
}
}
}
以策略取代条件表达式(Replace Conditional with Strategy): 多个条件表达式根据相同的条件选择不同的行为时,将条件表达式替换为策略模式,每个策略对象实现不同的行为。
// Before
double calculateDiscount(Order order) {
if (order.getTotalAmount() > 1000) {
return order.getTotalAmount() * 0.1;
} else {
return order.getTotalAmount() * 0.05;
}
}
// After
interface DiscountStrategy {
double applyDiscount(Order order);
}
class TenPercentDiscount implements DiscountStrategy {
@Override
public double applyDiscount(Order order) {
return order.getTotalAmount() * 0.1;
}
}
class FivePercentDiscount implements DiscountStrategy {
@Override
public double applyDiscount(Order order) {
return order.getTotalAmount() * 0.05;
}
}
合并重复的条件片段(Consolidate Duplicate Conditional Fragments): 多个条件片段执行相同的操作时,将重复的条件片段合并为一个条件片段,避免重复代码。
// Before
void applyDiscount(Order order) {
if (order.getTotalAmount() > 1000) {
order.setDiscount(order.getTotalAmount() * 0.1);
} else {
order.setDiscount(order.getTotalAmount() * 0.05);
}
sendEmail(order);
}
// After
void applyDiscount(Order order) {
double discount = (order.getTotalAmount() > 1000) ? 0.1 : 0.05;
order.setDiscount(order.getTotalAmount() * discount);
sendEmail(order);
}
移除与参数无关的代码(Remove Redundant Code): 条件表达式中存在与参数无关的冗余代码时,移除与参数无关的冗余代码,使得代码更加简洁。
// Before
boolean canApplyDiscount(Order order) {
if (order.isVerified() && order.getTotalAmount() > 100) {
return true;
} else {
return false;
}
}
// After
boolean canApplyDiscount(Order order) {
return order.isVerified() && order.getTotalAmount() > 100;
}
以查询取代临时变量(Replace Temp with Query): 使用临时变量保存计算结果,增加了代码的复杂性时,将临时变量替换为查询方法,使得代码更加清晰。
// Before
double calculateTotalPrice(Order order) {
double basePrice = order.getBasePrice();
return basePrice * 1.2;
}
// After
double calculateTotalPrice(Order order) {
return order.getBasePrice() * 1.2;
}
这些简化条件表达式的重构手法有助于提高代码的可读性、可维护性,并使得条件逻辑更加清晰。在应用这些手法时,要根据具体的情况选择合适的手法,确保代码的质量和可维护性。就像是用更简单的语言讲述故事,让代码更容易理解和维护。