策略模式
外观
概述[编辑 | 编辑源代码]
策略模式是一种行为型设计模式,允许在运行时选择算法的具体实现。其核心思想是将算法族(一组相关算法)封装为独立的类,使它们可以相互替换,且算法的变化不影响使用算法的客户端。
模板:Definition 定义一个算法族,将每个算法封装起来,并使它们可以互相替换。策略模式让算法的变化独立于使用算法的客户。
设计原则[编辑 | 编辑源代码]
策略模式体现了以下设计原则:
- 开闭原则:无需修改客户端代码即可扩展新算法
- 单一职责原则:每个算法类只负责一个具体策略
- 组合优于继承:通过对象组合而非继承来实现行为变化
结构[编辑 | 编辑源代码]
关键角色说明:
- Context:持有策略引用的环境类
- Strategy:策略接口(抽象策略)
- ConcreteStrategy:具体策略实现
代码示例[编辑 | 编辑源代码]
以下示例展示排序策略的可互换实现:
Java 实现[编辑 | 编辑源代码]
// 策略接口
interface SortStrategy {
void sort(int[] data);
}
// 具体策略A:冒泡排序
class BubbleSort implements SortStrategy {
@Override
public void sort(int[] data) {
System.out.println("使用冒泡排序");
// 实际排序实现...
}
}
// 具体策略B:快速排序
class QuickSort implements SortStrategy {
@Override
public void sort(int[] data) {
System.out.println("使用快速排序");
// 实际排序实现...
}
}
// 上下文类
class Sorter {
private SortStrategy strategy;
public void setStrategy(SortStrategy strategy) {
this.strategy = strategy;
}
public void executeSort(int[] data) {
strategy.sort(data);
}
}
// 客户端代码
public class Main {
public static void main(String[] args) {
Sorter sorter = new Sorter();
int[] data = {5, 2, 9, 1, 5};
sorter.setStrategy(new BubbleSort());
sorter.executeSort(data.clone());
sorter.setStrategy(new QuickSort());
sorter.executeSort(data.clone());
}
}
Python 实现[编辑 | 编辑源代码]
from abc import ABC, abstractmethod
# 策略接口
class SortStrategy(ABC):
@abstractmethod
def sort(self, data):
pass
# 具体策略
class BubbleSort(SortStrategy):
def sort(self, data):
print("使用冒泡排序")
# 实际排序实现...
class QuickSort(SortStrategy):
def sort(self, data):
print("使用快速排序")
# 实际排序实现...
# 上下文
class Sorter:
def __init__(self, strategy: SortStrategy):
self._strategy = strategy
def sort(self, data):
self._strategy.sort(data)
# 客户端
if __name__ == "__main__":
data = [5, 2, 9, 1, 5]
sorter = Sorter(BubbleSort())
sorter.sort(data.copy())
sorter = Sorter(QuickSort())
sorter.sort(data.copy())
应用场景[编辑 | 编辑源代码]
策略模式适用于以下情况:
- 需要动态切换算法时
- 有多个条件语句选择不同算法变体时
- 算法需要独立于使用它的客户端时
真实案例[编辑 | 编辑源代码]
电商系统折扣策略:
优缺点[编辑 | 编辑源代码]
相关模式[编辑 | 编辑源代码]
- 状态模式:策略模式类似,但策略模式中的策略是静态配置的,而状态模式中的状态会随着上下文自动变化
- 工厂模式:常与策略模式结合使用来创建具体策略对象
- 命令模式:将操作封装为对象,策略模式则是封装算法
数学表达[编辑 | 编辑源代码]
策略模式可以形式化表示为:
其中:
- 依赖于抽象策略
- 具体策略 实现策略接口
进阶思考[编辑 | 编辑源代码]
- 如何结合依赖注入框架管理策略?
- 策略模式与Lambda表达式的关系?
- 如何避免策略膨胀问题?