本文目录导读:

我将通过一个具体案例展示如何使用策略模式重构复杂的if-else逻辑。
原始代码:大量if-else
// 订单实体
public class Order {
private String type; // VIP, NORMAL, GROUP
private double amount;
private int points;
// 构造函数、getter/setter省略
}
// 价格计算器 - 充满if-else
public class PriceCalculator {
public double calculatePrice(Order order) {
// VIP订单:9折 + 积分抵扣
if ("VIP".equals(order.getType())) {
double price = order.getAmount() * 0.9;
// 每100积分抵扣5元
double discount = (order.getPoints() / 100) * 5;
return Math.max(0, price - discount);
}
// 普通订单:无折扣
else if ("NORMAL".equals(order.getType())) {
return order.getAmount();
}
// 团购订单:8折,但需要消费满1000
else if ("GROUP".equals(order.getType())) {
if (order.getAmount() < 1000) {
throw new RuntimeException("团购订单需满1000元");
}
return order.getAmount() * 0.8;
}
// 促销订单:7.5折,需要满500
else if ("PROMOTION".equals(order.getType())) {
if (order.getAmount() < 500) {
throw new RuntimeException("促销订单需满500元");
}
return order.getAmount() * 0.75;
}
// 其他类型默认处理
else {
return order.getAmount();
}
}
}
使用策略模式重构
定义策略接口
// 价格计算策略接口
public interface PriceStrategy {
double calculate(Order order);
// 策略的key,用于注册
String getType();
}
实现各个策略
// VIP策略
public class VipPriceStrategy implements PriceStrategy {
@Override
public double calculate(Order order) {
double price = order.getAmount() * 0.9;
double discount = (order.getPoints() / 100) * 5;
return Math.max(0, price - discount);
}
@Override
public String getType() {
return "VIP";
}
}
// 普通订单策略
public class NormalPriceStrategy implements PriceStrategy {
@Override
public double calculate(Order order) {
return order.getAmount();
}
@Override
public String getType() {
return "NORMAL";
}
}
// 团购策略
public class GroupPriceStrategy implements PriceStrategy {
@Override
public double calculate(Order order) {
if (order.getAmount() < 1000) {
throw new RuntimeException("团购订单需满1000元");
}
return order.getAmount() * 0.8;
}
@Override
public String getType() {
return "GROUP";
}
}
// 促销策略
public class PromotionPriceStrategy implements PriceStrategy {
@Override
public double calculate(Order order) {
if (order.getAmount() < 500) {
throw new RuntimeException("促销订单需满500元");
}
return order.getAmount() * 0.75;
}
@Override
public String getType() {
return "PROMOTION";
}
}
策略工厂
// 策略工厂,负责管理和获取策略
public class PriceStrategyFactory {
// 使用Map存储策略,避免if-else判断
private static final Map<String, PriceStrategy> STRATEGIES = new HashMap<>();
static {
// 注册所有策略
registerStrategy(new VipPriceStrategy());
registerStrategy(new NormalPriceStrategy());
registerStrategy(new GroupPriceStrategy());
registerStrategy(new PromotionPriceStrategy());
}
private static void registerStrategy(PriceStrategy strategy) {
STRATEGIES.put(strategy.getType(), strategy);
}
// 获取策略,如果找不到默认使用普通策略
public static PriceStrategy getStrategy(String type) {
PriceStrategy strategy = STRATEGIES.get(type);
if (strategy == null) {
return STRATEGIES.get("NORMAL"); // 默认策略
}
return strategy;
}
}
优化后的价格计算器
// 重构后的价格计算器
public class PriceCalculator {
public double calculatePrice(Order order) {
// 从工厂获取策略并执行
PriceStrategy strategy = PriceStrategyFactory.getStrategy(order.getType());
return strategy.calculate(order);
}
}
使用Spring方式(如果使用Spring框架)
// Spring IOC方式实现策略模式
@Component
public class PriceCalculatorV2 {
// Spring自动注入所有PriceStrategy实现类
@Autowired
private List<PriceStrategy> strategyList;
private Map<String, PriceStrategy> strategyMap = new HashMap<>();
// 使用ApplicationContext实现更灵活
@Autowired
private ApplicationContext applicationContext;
@PostConstruct
public void init() {
// 将所有的策略放入Map,key为策略类型
for (PriceStrategy strategy : strategyList) {
strategyMap.put(strategy.getType(), strategy);
}
}
public double calculatePrice(Order order) {
PriceStrategy strategy = strategyMap.getOrDefault(
order.getType(),
strategyMap.get("NORMAL") // 默认策略
);
return strategy.calculate(order);
}
// 或者使用Spring的依赖注入方式,通过名称获取Bean
public double calculatePriceWithAOP(Order order, String beanName) {
PriceStrategy strategy = (PriceStrategy) applicationContext.getBean(beanName);
return strategy.calculate(order);
}
}
客户端使用示例
public class Client {
public static void main(String[] args) {
PriceCalculator calculator = new PriceCalculator();
// 测试VIP订单
Order vipOrder = new Order();
vipOrder.setType("VIP");
vipOrder.setAmount(1000);
vipOrder.setPoints(200);
System.out.println("VIP价格: " + calculator.calculatePrice(vipOrder));
// 测试普通订单
Order normalOrder = new Order();
normalOrder.setType("NORMAL");
normalOrder.setAmount(1000);
System.out.println("普通价格: " + calculator.calculatePrice(normalOrder));
// 测试团购订单
Order groupOrder = new Order();
groupOrder.setType("GROUP");
groupOrder.setAmount(2000);
System.out.println("团购价格: " + calculator.calculatePrice(groupOrder));
// 测试不存在的类型
Order unknownOrder = new Order();
unknownOrder.setType("UNKNOWN");
unknownOrder.setAmount(500);
System.out.println("未知类型价格: " + calculator.calculatePrice(unknownOrder));
}
}
策略模式的优势
- 开闭原则:新增策略只需添加新类,无需修改现有代码
- 消除if-else:使用Map或Spring IOC管理策略,代码更清晰
- 可扩展性:可以动态注册、移除策略
- 可维护性:每个策略独立维护,职责单一
- 可测试性:策略可以独立测试
进一步优化建议
// 1. 使用枚举定义订单类型
public enum OrderType {
VIP("VIP"),
NORMAL("NORMAL"),
GROUP("GROUP");
private String value;
// getter、setter
}
// 2. 策略接口增加默认方法
public interface PriceStrategy {
double calculate(Order order);
String getType();
// 默认校验方法,子类可以重写
default void validate(Order order) {}
}
通过这种重构,代码的可维护性、可扩展性和可读性都有了显著提升。