策略模式(Strategy Pattern)是一种行为设计模式,它定义了一系列算法,并将每一个算法封装起来,使它们可以相互替换。从而可以根据需要选择不同的算法来处理某个任务,且客户端代码可以统一地操作这些算法而无需知道它们是如何实现的。
策略模式的核心是将算法的选择与使用算法的代码隔离开来,因而它在不修改原有代码的基础上能较为灵活地替换、增加新的算法。
策略模式的组成
-
策略接口(Strategy):
- 定义一个接口以支持一系列算法的实现。
-
具体策略类(Concrete Strategy):
- 实现策略接口,提供具体的算法实现。
-
上下文类(Context):
- 内部持有一个策略对象的引用,客户端通过上下文类与策略接口进行交互。
优势
- 开放-封闭原则:可以在不修改已有上下文类的情况下,更换、增加新的策略。
- 消除条件语句:避免在客户端中使用复杂的条件逻辑来选择行为。
- 策略可替换:允许动态替换算法或行为。
在C语言中的例子
由于C语言不是面向对象的语言,它没有类和接口,设计模式的实现通常依赖于函数指针。以下是一个简单的策略模式实现,用于执行不同类型的操作(例如,加法和乘法):
#include <stdio.h>
// 策略接口:定义用于操作的函数指针
typedef int (*StrategyFunction)(int, int);
// 具体策略实现:加法
int addStrategy(int a, int b) {
return a + b;
}
// 具体策略实现:乘法
int multiplyStrategy(int a, int b) {
return a * b;
}
// 上下文:维护一个指向策略的引用
typedef struct {
StrategyFunction strategy;
} Context;
// 设置上下文使用的策略
void setStrategy(Context* context, StrategyFunction strategy) {
context->strategy = strategy;
}
// 执行策略
int executeStrategy(Context* context, int a, int b) {
return context->strategy(a, b);
}
// 示例使用
int main() {
// 创建上下文对象
Context context;
// 设置策略为加法并执行
setStrategy(&context, addStrategy);
printf("Add Strategy: 5 + 3 = %d\n", executeStrategy(&context, 5, 3));
// 设置策略为乘法并执行
setStrategy(&context, multiplyStrategy);
printf("Multiply Strategy: 5 * 3 = %d\n", executeStrategy(&context, 5, 3));
return 0;
}
解释
- StrategyFunction:定义一个函数指针类型,用于代表各种策略。
- addStrategy 和 multiplyStrategy:分别实现加法和乘法策略。
- Context:持有策略函数指针,通过
setStrategy
函数动态设置策略,通过executeStrategy
函数来执行当前策略。 - 客户端:在
main
函数中,客户端通过上下文设置和执行不同的策略,展示了策略的动态替换特性。
通过这种方式,策略模式帮助我们用更简洁和灵活的方式来处理变动的算法需求,在增加功能时仅需新增策略而无需修改上下文和客户端代码,这也是策略模式的强大之处。