策略模式详解
一、模式定义
策略模式(Strategy Pattern)属于行为型模式,它定义了一系列算法,并将每个算法封装起来,使它们可以相互替换。
二、核心结构
1. 抽象策略接口
public interface Strategy {
void executeAlgorithm();
}
2. 具体策略实现
public class ConcreteStrategyA implements Strategy {
public void executeAlgorithm() {
System.out.println("执行策略A的算法逻辑");
// 具体算法实现...
}
}
public class ConcreteStrategyB implements Strategy {
public void executeAlgorithm() {
System.out.println("执行策略B的算法逻辑");
// 具体算法实现...
}
}
3. 上下文类
public class Context {
private Strategy strategy;
public Context(Strategy strategy) {
this.strategy = strategy;
}
public void setStrategy(Strategy strategy) {
this.strategy = strategy;
}
public void executeStrategy() {
strategy.executeAlgorithm();
}
}
三、完整示例:电商促销系统
1. 促销策略接口
public interface PromotionStrategy {
double applyPromotion(double originalPrice);
}
2. 具体促销策略
// 无促销
public class NoPromotion implements PromotionStrategy {
public double applyPromotion(double originalPrice) {
return originalPrice;
}
}
// 折扣促销
public class DiscountPromotion implements PromotionStrategy {
private double discountRate;
public DiscountPromotion(double discountRate) {
this.discountRate = discountRate;
}
public double applyPromotion(double originalPrice) {
return originalPrice * discountRate;
}
}
// 满减促销
public class FullReductionPromotion implements PromotionStrategy {
private double fullAmount;
private double reductionAmount;
public FullReductionPromotion(double fullAmount, double reductionAmount) {
this.fullAmount = fullAmount;
this.reductionAmount = reductionAmount;
}
public double applyPromotion(double originalPrice) {
return originalPrice >= fullAmount ?
originalPrice - reductionAmount :
originalPrice;
}
}
3. 订单类(上下文)
public class Order {
private double amount;
private PromotionStrategy promotionStrategy;
public Order(double amount) {
this.amount = amount;
this.promotionStrategy = new NoPromotion();
}
public void setPromotionStrategy(PromotionStrategy strategy) {
this.promotionStrategy = strategy;
}
public double calculateFinalPrice() {
return promotionStrategy.applyPromotion(amount);
}
}
4. 客户端使用
public class Client {
public static void main(String[] args) {
Order order = new Order(1000);
// 默认无促销
System.out.println("原价: " + order.calculateFinalPrice());
// 应用8折促销
order.setPromotionStrategy(new DiscountPromotion(0.8));
System.out.println("8折后: " + order.calculateFinalPrice());
// 应用满1000减200
order.setPromotionStrategy(new FullReductionPromotion(1000, 200));
System.out.println("满减后: " + order.calculateFinalPrice());
}
}
四、高级应用:策略工厂
1. 策略工厂类
public class PromotionStrategyFactory {
private static Map<String, PromotionStrategy> strategies = new HashMap<>();
static {
strategies.put("NO_PROMOTION", new NoPromotion());
strategies.put("DISCOUNT_8", new DiscountPromotion(0.8));
strategies.put("FULL_1000_REDUCE_200", new FullReductionPromotion(1000, 200));
}
public static PromotionStrategy getStrategy(String strategyKey) {
PromotionStrategy strategy = strategies.get(strategyKey);
if(strategy == null) {
throw new IllegalArgumentException("无效的策略类型");
}
return strategy;
}
}
2. 改进的订单类
public class ImprovedOrder {
private double amount;
private PromotionStrategy promotionStrategy;
public ImprovedOrder(double amount, String strategyKey) {
this.amount = amount;
this.promotionStrategy = PromotionStrategyFactory.getStrategy(strategyKey);
}
public double calculateFinalPrice() {
return promotionStrategy.applyPromotion(amount);
}
}
五、模式优势
- 符合
开闭原则
:新增策略无需修改现有代码 - 避免多重条件判断语句
- 提高算法的复用性和灵活性
- 算法可以自由切换
六、适用场景
- 系统需要在多种算法间动态切换
- 存在多个条件分支的复杂条件语句
- 需要隔离算法实现细节
- 算法需要自由组合的场景
七、注意事项
- 客户端必须了解所有策略的区别
- 会增加策略类的数量
- 策略对象会增大系统开销
- 适合算法经常变化的场景
八、与其他模式的关系
- 与
状态模式
:策略模式改变对象行为,状态模式改变对象状态 - 与
工厂模式
:常组合使用,策略工厂管理策略实例 - 与
模板方法模式
:都是封装算法,策略用组合,模板用继承
九、最佳实践
- 将策略定义为轻量级的无状态对象
- 使用枚举或工厂管理策略实例
- 考虑使用Lambda表达式简化策略实现(Java8+)
- 为策略接口提供合理的默认实现
- 保持策略接口的简洁性
十、完整示例代码结构
src/
├── main/
│ ├── java/
│ │ ├── strategy/
│ │ │ ├── PromotionStrategy.java
│ │ │ ├── NoPromotion.java
│ │ │ ├── DiscountPromotion.java
│ │ │ ├── FullReductionPromotion.java
│ │ │ ├── PromotionStrategyFactory.java
│ │ │ ├── Order.java
│ │ │ └── Client.java