在开发过程中,我们常常会遇到遗留系统中充斥着大量 if-else
语句的代码。这些代码不仅难以维护,还容易引入错误。本文将介绍如何通过多种方式优化 if-else
的使用,使代码更具可读性、可维护性和扩展性。
以下是一个典型的 if-else
代码片段,用于根据运输类型计算运费:
public class ShippingCostCalculator {
public double calculateShippingCost(String shippingType, double weight) {
if (shippingType.equals("STANDARD")) {
return weight * 5.0;
} elseif (shippingType.equals("EXPRESS")) {
return weight * 10.0;
} elseif (shippingType.equals("SAME_DAY")) {
return weight * 20.0;
} elseif (shippingType.equals("INTERNATIONAL")) {
return weight * 50.0;
} elseif (shippingType.equals("OVERNIGHT")) {
return weight * 30.0;
}
return0;
}
}
:过多的 if-else
语句使代码难以阅读。
:添加新的运输类型需要修改核心逻辑。
:字符串比较容易拼写错误,且缺乏类型安全性。
枚举是一种类型安全的方式,可以有效地替代 if-else
语句。
public enum ShippingType {
STANDARD {
@Override
public double getCost(double weight) {
return weight * 5.0;
}
},
EXPRESS {
@Override
public double getCost(double weight) {
return weight * 10.0;
}
},
SAME_DAY {
@Override
public double getCost(double weight) {
return weight * 20.0;
}
},
INTERNATIONAL {
@Override
public double getCost(double weight) {
return weight * 50.0;
}
},
OVERNIGHT {
@Override
public double getCost(double weight) {
return weight * 30.0;
}
};
public abstract double getCost(double weight);
}
public class ShippingCostCalculator {
public double calculateShippingCost(ShippingType shippingType, double weight) {
return shippingType.getCost(weight);
}
}
public class MainCost {
public static void main(String[] args) {
var calculator = new ShippingCostCalculator();
var cost = calculator.calculateShippingCost(ShippingType.EXPRESS, 2.5);
System.out.println("Shipping cost: " + cost);
}
}
:避免字符串比较错误。
:添加新的运输类型只需扩展枚举。
:每种运输类型的逻辑独立且易于理解。
:如果需要添加更多参数,枚举会变得繁琐。
:枚举不能继承其他类,限制了代码复用。
工厂模式通过将对象的创建与使用分离,进一步优化代码结构。
public interface ShippingCostStrategy {
double calculate(double weight);
}
public class StandardShipping implements ShippingCostStrategy {
@Override
public double calculate(double weight) {
return weight * 5.0;
}
}
publicclass ExpressShipping implements ShippingCostStrategy {
@Override
public double calculate(double weight) {
return weight * 10.0;
}
}
publicclass SameDayShipping implements ShippingCostStrategy {
@Override
public double calculate(double weight) {
return weight * 20.0;
}
}
publicclass InternationalShipping implements ShippingCostStrategy {
@Override
public double calculate(double weight) {
return weight * 50.0;
}
}
publicclass OvernightShipping implements ShippingCostStrategy {
@Override
public double calculate(double weight) {
return weight * 30.0;
}
}
import java.util.HashMap;
import java.util.Map;
publicclass ShippingCostFactory {
privatestaticfinal Map strategies = new HashMap<>();
static {
strategies.put("STANDARD", new StandardShipping());
strategies.put("EXPRESS", new ExpressShipping());
strategies.put("SAME_DAY", new SameDayShipping());
strategies.put("INTERNATIONAL", new InternationalShipping());
strategies.put("OVERNIGHT", new OvernightShipping());
}
public static ShippingCostStrategy getStrategy(String shippingType) {
ShippingCostStrategy strategy = strategies.get(shippingType);
if (strategy == null) {
thrownew IllegalArgumentException("Invalid shipping type: " + shippingType);
}
return strategy;
}
}
public class ShippingCostCalculator {
public double calculateShippingCost(String shippingType, double weight) {
ShippingCostStrategy strategy = ShippingCostFactory.getStrategy(shippingType);
return strategy.calculate(weight);
}
}
:添加新的运输类型只需创建新的策略类并更新工厂。
:每种运输类型的逻辑独立,易于维护。
:工厂可以根据需要返回不同的策略。
策略模式与工厂模式类似,但更侧重于动态切换算法。
public interface ShippingCostStrategy {
double calculate(double weight);
}
public class StandardShipping implements ShippingCostStrategy {
@Override
public double calculate(double weight) {
return weight * 5.0;
}
}
publicclass ExpressShipping implements ShippingCostStrategy {
@Override
public double calculate(double weight) {
return weight * 10.0;
}
}
publicclass SameDayShipping implements ShippingCostStrategy {
@Override
public double calculate(double weight) {
return weight * 20.0;
}
}
publicclass InternationalShipping implements ShippingCostStrategy {
@Override
public double calculate(double weight) {
return weight * 50.0;
}
}
publicclass OvernightShipping implements ShippingCostStrategy {
@Override
public double calculate(double weight) {
return weight * 30.0;
}
}
public class ShippingCostContext {
private ShippingCostStrategy strategy;
public void setStrategy(ShippingCostStrategy strategy) {
this.strategy = strategy;
}
public double calculateShippingCost(double weight) {
return strategy.calculate(weight);
}
}
import java.util.HashMap;
import java.util.Map;
publicclass ShippingCostCalculator {
privatestaticfinal Map strategies = new HashMap<>();
static {
strategies.put("STANDARD", new StandardShipping());
strategies.put("EXPRESS", new ExpressShipping());
strategies.put("SAME_DAY", new SameDayShipping());
strategies.put("INTERNATIONAL", new InternationalShipping());
strategies.put("OVERNIGHT", new OvernightShipping());
}
privatefinal ShippingCostContext context = new ShippingCostContext();
public double calculateShippingCost(String shippingType, double weight) {
ShippingCostStrategy strategy = strategies.get(shippingType);
if (strategy == null) {
thrownew IllegalArgumentException("Invalid shipping type: " + shippingType);
}
context.setStrategy(strategy);
return context.calculateShippingCost(weight);
}
}
public class MainCost {
public static void main(String[] args) {
ShippingCostCalculator calculator = new ShippingCostCalculator();
double weight = 10.0;
String shippingType1 = "STANDARD";
double cost1 = calculator.calculateShippingCost(shippingType1, weight);
System.out.println("Shipping cost for " + shippingType1 + ": " + cost1);
String shippingType2 = "EXPRESS";
double cost2 = calculator.calculateShippingCost(shippingType2, weight);
System.out.println("Shipping cost for " + shippingType2 + ": " + cost2);
String shippingType3 = "SAME_DAY";
double cost3 = calculator.calculateShippingCost(shippingType3, weight);
System.out.println("Shipping cost for " + shippingType3 + ": " + cost3);
String shippingType4 = "INTERNATIONAL";
double cost4 = calculator.calculateShippingCost(shippingType4, weight);
System.out.println("Shipping cost for " + shippingType4 + ": " + cost4);
String shippingType5 = "OVERNIGHT";
double cost5 = calculator.calculateShippingCost(shippingType5, weight);
System.out.println("Shipping cost for " + shippingType5 + ": " + cost5);
}
}
:可以在运行时动态切换不同的计算策略。
:每种策略的实现独立,易于维护和扩展。
对于简单的场景,可以使用 Java 8 的 Stream API 和 Map 来优化代码。
import java.util.HashMap;
import java.util.Map;
publicclass ShippingCostCalculator {
privatestaticfinal Map shippingCosts = new HashMap<>();
static {
shippingCosts.put("STANDARD", 5.0);
shippingCosts.put("EXPRESS", 10.0);
shippingCosts.put("SAME_DAY", 20.0);
shippingCosts.put("INTERNATIONAL", 50.0);
shippingCosts.put("OVERNIGHT", 30.0);
}
public double calculateShippingCost(String shippingType, double weight) {
return shippingCosts.entrySet().stream()
.filter(entry -> entry.getKey().equalsIgnoreCase(shippingType))
.map(Map.Entry::getValue)
.findFirst()
.orElse(0.0)
* weight;
}
public static void main(String[] args) {
ShippingCostCalculator calculator = new ShippingCostCalculator();
double weight = 10.0;
String shippingType1 = "STANDARD";
double cost1 = calculator.calculateShippingCost(shippingType1, weight);
System.out.println("Shipping cost for " + shippingType1 + ": " + cost1);
String shippingType2 = "EXPRESS";
double cost2 = calculator.calculateShippingCost(shippingType2, weight);
System.out.println("Shipping cost for " + shippingType2 + ": " + cost2);
String shippingType3 = "SAME_DAY";
double cost3 = calculator.calculateShippingCost(shippingType3, weight);
System.out.println("Shipping cost for " + shippingType3 + ": " + cost3);
String shippingType4 = "INTERNATIONAL";
double cost4 = calculator.calculateShippingCost(shippingType4, weight);
System.out.println("Shipping cost for " + shippingType4 + ": " + cost4);
String shippingType5 = "OVERNIGHT";
double cost5 = calculator.calculateShippingCost(shippingType5, weight);
System.out.println("Shipping cost for " + shippingType5 + ": " + cost5);
String invalidType = "INVALID";
double invalidCost = calculator.calculateShippingCost(invalidType, weight);
System.out.println("Shipping cost for " + invalidType + ": " + invalidCost);
}
}
:代码简洁,适合简单场景。
:无需定义额外的类或接口。
:不适合复杂的业务逻辑。
通过枚举、工厂模式、策略模式和 Stream API,我们可以有效地优化 if-else
语句,使代码更具可读性、可维护性和扩展性。选择哪种优化方式取决于具体的业务场景和需求。