策略模式
介绍
策略模式(Strategy Pattern)是一种行为型设计模式,它定义了一系列算法,并将每个算法封装起来,使它们可以互相替换。策略模式让算法的变化独立于使用算法的客户。
原理
策略模式的核心原理包括:
- 策略接口:定义所有支持的算法的公共接口
- 具体策略:实现策略接口的具体算法
- 上下文:持有一个策略对象的引用,提供一个接口供客户端调用
- 客户端:创建具体策略对象,并将其传递给上下文
图示
+----------------+ +----------------+
| 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));
}
}
解决方案
应用场景
- 算法选择:当有多个算法可以解决同一个问题,且需要动态切换时
- 消除条件语句:用策略模式替代复杂的条件判断语句
- 开闭原则:当需要添加新算法时,无需修改现有代码
- 参数化行为:将算法作为参数传递给其他方法
- 封装变化:将变化的部分封装在策略类中
最佳实践
- 保持策略接口简洁:只包含必要的方法
- 避免策略类过于复杂:每个策略类专注于一个算法
- 使用工厂模式创建策略:结合工厂模式管理策略对象的创建
- 考虑使用享元模式:当策略对象可以共享时
- 使用注解或配置文件:在大型应用中,通过注解或配置文件注册策略
优缺点
优点:
- 实现算法的复用和切换
- 消除条件语句
- 符合开闭原则
- 提高代码的可测试性
缺点:
- 增加类的数量
- 客户端必须了解所有策略
- 策略之间的通信可能变得复杂
工具推荐
- Java 8+ Lambda表达式:简化策略模式的实现
- Spring Framework:通过依赖注入管理策略对象
- Google Guice:提供@Inject注解和模块系统实现策略模式
- Apache Commons Collections:提供策略接口和实现
- Strategy Pattern Generator:IntelliJ IDEA插件,自动生成策略模式代码