一、策略模式基础概念
策略模式(Strategy Pattern) 是一种行为型设计模式,它通过定义一系列可互换的算法族,并将每个算法封装成独立的策略类,使得算法可以独立于使用它的客户端变化。策略模式的核心思想是 “将算法的定义与使用分离”,从而解决在复杂业务场景中因条件分支过多导致的代码臃肿、维护困难等问题。
核心角色
- 环境类(Context):持有策略对象的引用,负责调用具体策略。
- 抽象策略(Strategy):定义算法接口,声明策略方法的规范。
- 具体策略(Concrete Strategy):实现抽象策略接口,提供具体的算法实现。
二、简单案例:支付方式选择
假设需要实现一个支持多种支付方式的系统(支付宝、微信、银行卡),通过策略模式可以灵活扩展支付方式,避免冗长的 if-else
判断。
1. 定义抽象策略接口
public interface PaymentStrategy {
void pay(double amount);
}
2. 实现具体策略类
// 支付宝支付
public class AlipayStrategy implements PaymentStrategy {
@Override
public void pay(double amount) {
System.out.println("支付宝支付:" + amount + "元");
}
}
// 微信支付
public class WechatPayStrategy implements PaymentStrategy {
@Override
public void pay(double amount) {
System.out.println("微信支付:" + amount + "元");
}
}
3. 环境类封装策略调用
public class PaymentContext {
private PaymentStrategy strategy;
public PaymentContext(PaymentStrategy strategy) {
this.strategy = strategy;
}
public void executePayment(double amount) {
strategy.pay(amount);
}
}
4. 客户端调用
public class Client {
public static void main(String[] args) {
PaymentContext context = new PaymentContext(new AlipayStrategy());
context.executePayment(100.0); // 输出:支付宝支付:100.0元
context = new PaymentContext(new WechatPayStrategy());
context.executePayment(200.0); // 输出:微信支付:200.0元
}
}
三、项目实践案例:电商促销活动
在电商系统中,促销活动类型多样(如满减、折扣、赠品),不同活动需要动态切换计算逻辑。策略模式可优雅解决这类需求。
1. 业务场景分析
- 需求:根据活动类型计算订单最终价格。
- 痛点:直接使用
if-else
判断活动类型会导致代码臃肿,新增活动需修改核心逻辑。
2. 策略模式实现
定义促销策略接口
public interface PromotionStrategy {
double applyPromotion(double originalPrice);
}
实现具体促销策略
// 满减策略:满300减50
public class FullReductionStrategy implements PromotionStrategy {
@Override
public double applyPromotion(double originalPrice) {
return originalPrice >= 300 ? originalPrice - 50 : originalPrice;
}
}
// 折扣策略:8折优惠
public class DiscountStrategy implements PromotionStrategy {
@Override
public double applyPromotion(double originalPrice) {
return originalPrice * 0.8;
}
}
环境类封装策略选择
public class PromotionContext {
private PromotionStrategy strategy;
public void setStrategy(PromotionStrategy strategy) {
this.strategy = strategy;
}
public double calculateFinalPrice(double originalPrice) {
return strategy.applyPromotion(originalPrice);
}
}
结合工厂模式动态获取策略(增强扩展性)
public class PromotionStrategyFactory {
private static final Map<String, PromotionStrategy> strategies = new HashMap<>();
static {
strategies.put("FULL_REDUCTION", new FullReductionStrategy());
strategies.put("DISCOUNT", new DiscountStrategy());
}
public static PromotionStrategy getStrategy(String promotionType) {
return strategies.get(promotionType);
}
}
客户端调用示例
public class OrderService {
public double calculateOrderPrice(String promotionType, double originalPrice) {
PromotionStrategy strategy = PromotionStrategyFactory.getStrategy(promotionType);
PromotionContext context = new PromotionContext();
context.setStrategy(strategy);
return context.calculateFinalPrice(originalPrice);
}
}
// 测试输出
OrderService service = new OrderService();
System.out.println(service.calculateOrderPrice("FULL_REDUCTION", 350)); // 300.0
System.out.println(service.calculateOrderPrice("DISCOUNT", 200)); // 160.0
四、策略模式的优势与适用场景
优势
- 开闭原则:新增策略无需修改已有代码。
- 消除条件分支:避免
if-else
或switch-case
的泛滥。 - 算法复用:策略对象可跨模块共享。
适用场景
- 业务规则动态切换:如支付方式、促销活动、风控规则。
- 算法需要独立演化:如排序算法、数据加密方式。
- 隐藏复杂逻辑:如第三方服务调用(不同渠道短信发送)。
五、总结
策略模式通过将算法封装为独立对象,赋予系统高度的灵活性和扩展性。在实际项目中,策略模式常与工厂模式、Spring 容器管理结合,通过依赖注入动态选择策略。但需注意:若策略数量过多,需考虑使用 策略枚举 或 配置中心 统一管理,避免策略类膨胀。