Java策略模式重构if案例

wen java案例 3

本文目录导读:

Java策略模式重构if案例

  1. 原始代码:大量if-else
  2. 使用策略模式重构
  3. 策略模式的优势
  4. 进一步优化建议

我将通过一个具体案例展示如何使用策略模式重构复杂的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));
    }
}

策略模式的优势

  1. 开闭原则:新增策略只需添加新类,无需修改现有代码
  2. 消除if-else:使用Map或Spring IOC管理策略,代码更清晰
  3. 可扩展性:可以动态注册、移除策略
  4. 可维护性:每个策略独立维护,职责单一
  5. 可测试性:策略可以独立测试

进一步优化建议

// 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) {}
}

通过这种重构,代码的可维护性、可扩展性和可读性都有了显著提升。

抱歉,评论功能暂时关闭!