跳到主要内容

策略模式

介绍

策略模式(Strategy Pattern)是一种行为型设计模式,它定义了一系列算法,并将每个算法封装起来,使它们可以互相替换。策略模式让算法的变化独立于使用算法的客户。

原理

策略模式的核心原理包括:

  1. 策略接口:定义所有支持的算法的公共接口
  2. 具体策略:实现策略接口的具体算法
  3. 上下文:持有一个策略对象的引用,提供一个接口供客户端调用
  4. 客户端:创建具体策略对象,并将其传递给上下文

图示

+----------------+        +----------------+
| Strategy | | Context |
+----------------+ +----------------+
| + algorithm() |<-------| - strategy |
+-------^--------+ | + setStrategy()|
| | + contextInterface()|
+-------+--------+ +----------------+
| ConcreteStrategyA|
+----------------+
| + algorithm() |
+----------------+

+----------------+
| ConcreteStrategyB|
+----------------+
| + algorithm() |
+----------------+

+----------------+
| ConcreteStrategyC|
+----------------+
| + algorithm() |
+----------------+

代码示例

策略接口

public interface Strategy {
int algorithm(int a, int b);
}

具体策略

public class ConcreteStrategyAdd implements Strategy {
@Override
public int algorithm(int a, int b) {
return a + b;
}
}

public class ConcreteStrategySubtract implements Strategy {
@Override
public int algorithm(int a, int b) {
return a - b;
}
}

public class ConcreteStrategyMultiply implements Strategy {
@Override
public int algorithm(int a, int b) {
return a * b;
}
}

上下文

public class Context {
private Strategy strategy;

public Context(Strategy strategy) {
this.strategy = strategy;
}

public void setStrategy(Strategy strategy) {
this.strategy = strategy;
}

public int executeStrategy(int a, int b) {
return strategy.algorithm(a, b);
}
}

客户端代码

public class Client {
public static void main(String[] args) {
Context context = new Context(new ConcreteStrategyAdd());
System.out.println("10 + 5 = " + context.executeStrategy(10, 5));

context.setStrategy(new ConcreteStrategySubtract());
System.out.println("10 - 5 = " + context.executeStrategy(10, 5));

context.setStrategy(new ConcreteStrategyMultiply());
System.out.println("10 * 5 = " + context.executeStrategy(10, 5));
}
}

解决方案

应用场景

  1. 算法选择:当有多个算法可以解决同一个问题,且需要动态切换时
  2. 消除条件语句:用策略模式替代复杂的条件判断语句
  3. 开闭原则:当需要添加新算法时,无需修改现有代码
  4. 参数化行为:将算法作为参数传递给其他方法
  5. 封装变化:将变化的部分封装在策略类中

最佳实践

  1. 保持策略接口简洁:只包含必要的方法
  2. 避免策略类过于复杂:每个策略类专注于一个算法
  3. 使用工厂模式创建策略:结合工厂模式管理策略对象的创建
  4. 考虑使用享元模式:当策略对象可以共享时
  5. 使用注解或配置文件:在大型应用中,通过注解或配置文件注册策略

优缺点

优点

  • 实现算法的复用和切换
  • 消除条件语句
  • 符合开闭原则
  • 提高代码的可测试性

缺点

  • 增加类的数量
  • 客户端必须了解所有策略
  • 策略之间的通信可能变得复杂

工具推荐

  1. Java 8+ Lambda表达式:简化策略模式的实现
  2. Spring Framework:通过依赖注入管理策略对象
  3. Google Guice:提供@Inject注解和模块系统实现策略模式
  4. Apache Commons Collections:提供策略接口和实现
  5. Strategy Pattern Generator:IntelliJ IDEA插件,自动生成策略模式代码