策略模式是一种行为型设计模式,它的核心思想是将不同的算法封装到独立的策略类中,让这些策略类实现同一个接口,客户端可以根据实际需求动态选择使用不同的策略,不需要修改客户端本身的代码逻辑,从而实现算法的灵活切换。

策略模式的核心结构
策略模式的实现通常包含三个核心角色,每个角色的职责清晰划分,共同完成算法的封装和切换功能:
- 策略接口:定义所有支持的算法的公共接口,所有具体的策略类都需要实现这个接口中的方法。
- 具体策略类:实现策略接口,封装具体的算法逻辑,每个具体策略类对应一种特定的算法实现。
- 上下文类:持有一个策略对象的引用,负责维护当前使用的策略,并且提供一个方法让客户端可以设置或者切换策略,同时调用策略对象的方法完成具体的算法执行。
C++实现策略模式的步骤
1. 定义策略接口
首先我们需要定义一个策略接口,里面声明所有算法都需要实现的方法,这里以排序算法为例,定义一个排序策略接口:
// 排序策略接口
class SortStrategy {
public:
// 纯虚函数,定义排序算法的公共接口
virtual void sort(int* arr, int length) = 0;
// 虚析构函数,保证派生类析构正确调用
virtual ~SortStrategy() {}
};
2. 实现具体策略类
接下来实现两种不同的排序策略,分别是冒泡排序和快速排序,两个类都继承SortStrategy并实现sort方法:
// 冒泡排序具体策略
class BubbleSortStrategy : public SortStrategy {
public:
void sort(int* arr, int length) override {
if (arr == nullptr || length <= 1) {
return;
}
for (int i = 0; i < length - 1; i++) {
for (int j = 0; j < length - 1 - i; j++) {
if (arr[j] > arr[j + 1]) {
int temp = arr[j];
arr[j] = arr[j + 1];
arr[j + 1] = temp;
}
}
}
printf("使用冒泡排序完成排序n");
}
};
// 快速排序具体策略
class QuickSortStrategy : public SortStrategy {
private:
// 快速排序内部递归函数
void quickSort(int* arr, int left, int right) {
if (left >= right) {
return;
}
int pivot = arr[left];
int i = left;
int j = right;
while (i < j) {
while (i < j && arr[j] >= pivot) {
j--;
}
arr[i] = arr[j];
while (i < j && arr[i] <= pivot) {
i++;
}
arr[j] = arr[i];
}
arr[i] = pivot;
quickSort(arr, left, i - 1);
quickSort(arr, i + 1, right);
}
public:
void sort(int* arr, int length) override {
if (arr == nullptr || length <= 1) {
return;
}
quickSort(arr, 0, length - 1);
printf("使用快速排序完成排序n");
}
};
3. 实现上下文类
上下文类负责持有策略对象,并且提供切换策略和调用策略的方法:
// 排序上下文类
class SortContext {
private:
SortStrategy* strategy;
public:
SortContext() : strategy(nullptr) {}
// 设置当前使用的排序策略
void setStrategy(SortStrategy* newStrategy) {
strategy = newStrategy;
}
// 执行排序操作
void doSort(int* arr, int length) {
if (strategy == nullptr) {
printf("未设置排序策略,无法执行排序n");
return;
}
strategy->sort(arr, length);
}
~SortContext() {
// 注意:这里不负责释放strategy的内存,避免重复释放问题
// 实际开发中可以根据内存管理规则调整
}
};
4. 客户端使用示例
客户端代码可以根据需求动态切换不同的排序策略,不需要修改上下文和策略类的代码:
#include <cstdio>
// 上面的策略接口、具体策略类、上下文类定义放在这里
int main() {
int arr1[] = {5, 3, 8, 1, 2};
int arr2[] = {5, 3, 8, 1, 2};
int length = sizeof(arr1) / sizeof(arr1[0]);
SortContext context;
// 使用冒泡排序策略
BubbleSortStrategy bubbleSort;
context.setStrategy(&bubbleSort);
context.doSort(arr1, length);
// 切换到快速排序策略
QuickSortStrategy quickSort;
context.setStrategy(&quickSort);
context.doSort(arr2, length);
return 0;
}
策略模式的优势与适用场景
使用策略模式封装算法有以下几个明显的优势:
- 算法可以自由切换,客户端只需要更换策略对象就可以使用不同的算法,不需要修改自身代码。
- 避免了大量的条件判断语句,比如不需要用if else或者switch case判断使用哪种排序,降低代码复杂度。
- 符合开闭原则,如果需要新增新的算法,只需要新增一个具体策略类实现策略接口即可,不需要修改现有代码。
策略模式适合以下场景使用:
- 一个系统需要多种类似的算法,并且这些算法可以互相替换。
- 一个类有多种行为,这些行为在类中通过条件语句判断实现,导致类代码臃肿。
- 需要对外隐藏算法的具体实现细节,只暴露统一的接口。
注意事项
在使用C++实现策略模式的时候需要注意几个问题:
- 策略接口中的析构函数需要定义为虚函数,避免删除派生类对象的时候出现未定义行为。
- 上下文类持有策略对象的生命周期管理需要根据实际情况处理,上面的示例中策略对象由客户端创建,上下文不负责释放,实际开发中可以使用智能指针管理策略对象的生命周期。
- 如果策略类数量过多,会导致类的数量增加,需要根据实际情况权衡是否使用策略模式。
C++_strategy_pattern算法封装设计模式代码灵活性修改时间:2026-07-23 03:03:36