策略模式(Strategy Pattern)是一种行为设计模式,它定义了一系列算法,并将每个算法封装起来,使它们可以相互替换。策略模式使得算法可以独立于使用它的客户端而变化。
主要角色
- Strategy(策略): 策略接口,定义了一个算法族。
- ConcreteStrategy(具体策略): 实现策略接口的具体算法。
- Context(上下文): 维护一个策略对象的引用,并且可以根据需要调用策略对象的方法。
类图
+----------------+ +----------------+
| Context | | Strategy |
+----------------+ +----------------+
| - strategy |<---->| + algorithm() |
| + setStrategy()| +----------------+
| + execute() | ^
+----------------+ |
^ |
| |
+----------------+ +----------------+
|ConcreteStrategyA| |ConcreteStrategyB|
+----------------+ +----------------+
| + algorithm() | | + algorithm() |
+----------------+ +----------------+
示例代码
以下是一个简单的策略模式实现示例,使用了 Java 语言:
// 策略接口
interface Strategy {
void algorithm();
}
// 具体策略A
class ConcreteStrategyA implements Strategy {
@Override
public void algorithm() {
System.out.println("Executing Strategy A");
}
}
// 具体策略B
class ConcreteStrategyB implements Strategy {
@Override
public void algorithm() {
System.out.println("Executing Strategy B");
}
}
// 上下文
class Context {
private Strategy strategy;
public void setStrategy(Strategy strategy) {
this.strategy = strategy;
}
public void executeStrategy() {
strategy.algorithm();
}
}
// 使用示例
public class StrategyPatternDemo {
public static void main(String[] args) {
Context context = new Context();
// 使用策略A
context.setStrategy(new ConcreteStrategyA());
context.executeStrategy(); // Output: Executing Strategy A
// 使用策略B
context.setStrategy(new ConcreteStrategyB());
context.executeStrategy(); // Output: Executing Strategy B
}
}
使用场景
策略模式适用于以下场景:
- 需要使用多种算法: 一个系统需要使用多种算法,并且这些算法可以互换。
- 算法在客户端代码中使用: 算法的实现细节对客户端代码透明。
- 避免使用条件语句: 需要避免使用大量的条件语句来选择不同的算法。
优缺点
优点:
- 开闭原则: 可以在不修改上下文类的情况下增加新的策略。
- 消除条件语句: 通过使用策略模式,可以消除在客户端代码中使用的条件语句。
- 提高算法的可复用性: 不同的策略类可以复用相同的算法代码。
缺点:
- 类的数量增加: 每个具体策略都需要定义一个类,可能导致类的数量增加。
- 客户端必须知道所有策略: 客户端必须知道所有的策略,并且自行选择一个策略。
策略模式通过将算法封装到独立的策略类中,使得算法可以独立于使用它的客户端而变化。它在需要动态选择和更换算法的场景中非常有用。