行为型模式:⑨策略模式(Strategy Pattern)
核心思想
定义一系列可互换的算法(策略),将每个算法封装为独立的类/结构体,使算法的选择、切换与使用算法的客户端(上下文)分离。核心价值是:
- 消除大量
if-else/switch条件判断,用“组合+多态”替代硬编码的条件分支; - 算法可动态切换,客户端可根据需求在运行时选择不同策略;
- 新增/修改算法时无需修改客户端和其他策略,仅需新增/调整策略类,符合“开闭原则”;
- 算法复用性强,同一策略可被多个客户端共享。
核心本质
算法封装+动态委派,将“做什么”(客户端需求)与“怎么做”(具体算法)解耦,让算法成为可灵活替换的“组件”。
典型场景
- 支付方式选择(支付宝、微信、银行卡支付,不同支付算法可切换);
- 排序算法切换(冒泡排序、快速排序、归并排序,根据数据量动态选择);
- 折扣计算(会员折扣、节日折扣、满减折扣,不同场景自动切换);
- 数据校验规则(手机号校验、邮箱校验、身份证校验,按需选择校验策略)。
C语言实现(结构体+函数指针+组合)
C语言无类和继承,通过“结构体模拟策略接口”“函数指针定义算法行为”“上下文持有策略指针”,实现算法的封装与动态切换。核心是:上下文通过策略指针调用具体算法,切换策略只需修改指针指向。
场景示例
订单支付系统:
- 抽象策略(PaymentStrategy):用函数指针定义统一支付接口(
pay); - 具体策略:支付宝支付(AlipayStrategy)、微信支付(WechatPayStrategy)、银行卡支付(BankCardStrategy),实现各自的支付逻辑;
- 上下文(Order):持有当前支付策略指针,提供切换策略、执行支付的接口,维护订单金额等上下文数据。
实现代码
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
// 最大支付备注长度
#define MAX_REMARK_LEN 64
// -------------------------- 1. 抽象策略(PaymentStrategy):统一算法接口 --------------------------
// 策略结构体:包含支付函数指针(核心接口)和策略名称
typedef struct PaymentStrategy {
const char* name; // 策略名称(用于日志)
// 支付算法:接收订单金额、备注,返回支付结果(0=成功,-1=失败)
int (*pay)(float amount, const char* remark);
} PaymentStrategy;
// -------------------------- 2. 具体策略实现(不同支付方式) --------------------------
// 具体策略1:支付宝支付
int alipay_pay(float amount, const char* remark) {
printf("\n=== 【%s】 ===\n", "支付宝支付");
printf("支付金额:%.2f 元\n", amount);
printf("备注:%s\n", remark);
printf("执行支付宝支付逻辑(调用支付宝SDK、验证签名...)\n");
printf("支付宝支付成功!\n");
return 0;
}
// 支付宝策略实例(全局静态变量,无需动态分配)
PaymentStrategy AlipayStrategy = {
.name = "支付宝支付",
.pay = alipay_pay
};
// 具体策略2:微信支付
int wechat_pay(float amount, const char* remark) {
printf("\n=== 【%s】 ===\n", "微信支付");
printf("支付金额:%.2f 元\n", amount);
printf("备注:%s\n", remark);
printf("执行微信支付逻辑(调用微信SDK、验证openid...)\n");
printf("微信支付成功!\n");
return 0;
}
// 微信策略实例
PaymentStrategy WechatPayStrategy = {
.name = "微信支付",
.pay = wechat_pay
};
// 具体策略3:银行卡支付
int bank_card_pay(float amount, const char* remark) {
printf("\n=== 【%s】 ===\n", "银行卡支付");
printf("支付金额:%.2f 元\n", amount);
printf("备注:%s\n", remark);
printf("执行银行卡支付逻辑(验证卡号、密码、短信验证码...)\n");
printf("银行卡支付成功!\n");
return 0;
}
// 银行卡策略实例
PaymentStrategy BankCardStrategy = {
.name = "银行卡支付",
.pay = bank_card_pay
};
// -------------------------- 3. 上下文(Order):使用策略的客户端 --------------------------
typedef struct Order {
float amount; // 订单金额(上下文数据)
PaymentStrategy* current_strategy; // 持有当前策略指针(核心)
// 上下文操作接口
void (*set_strategy)(struct Order* self, PaymentStrategy* strategy); // 切换策略
int (*pay_order)(struct Order* self, const char* remark); // 执行支付(委派给策略)
void (*destroy)(struct Order* self);
} Order;
// 上下文:切换策略
void order_set_strategy(Order* self, PaymentStrategy* strategy) {
if (strategy == NULL) {
printf("错误:支付策略不能为空!\n");
return;
}
self->current_strategy = strategy;
printf("已切换支付方式为:%s\n", strategy->name);
}
// 上下文:执行支付(委托当前策略处理)
int order_pay_order(Order* self, const char* remark) {
if (self->current_strategy == NULL) {
printf("错误:未选择支付方式!\n");
return -1;
}
printf("订单开始支付,金额:%.2f 元\n", self->amount);
// 委派给当前策略的pay方法(核心:算法调用解耦)
return self->current_strategy->pay(self->amount, remark);
}
// 上下文:销毁
void order_destroy(Order* self) {
free(self);
printf("\n订单对象已销毁\n");
}
// 创建订单(上下文)
Order* create_order(float amount) {
Order* order = (Order*)malloc(sizeof(Order));
if (order == NULL) {
perror("malloc failed");
exit(EXIT_FAILURE);
}
order->amount = amount;
order->current_strategy = NULL; // 初始未选择策略
order->set_strategy = order_set_strategy;
order->pay_order = order_pay_order;
order->destroy = order_destroy;
printf("创建订单成功,金额:%.2f 元\n", amount);
return order;
}
// -------------------------- 测试代码(客户端) --------------------------
int main() {
// 1. 创建订单(上下文)
Order* order = create_order(299.99f);
printf("========================================\n");
// 2. 选择支付宝支付(切换策略1)
order->set_strategy(order, &AlipayStrategy);
order->pay_order(order, "购买电子产品");
// 3. 切换为微信支付(切换策略2)
printf("\n========================================\n");
order->set_strategy(order, &WechatPayStrategy);
order->pay_order(order, "购买电子产品(微信补付)");
// 4. 切换为银行卡支付(切换策略3)
printf("\n========================================\n");
order->set_strategy(order, &BankCardStrategy);
order->pay_order(order, "购买电子产品(银行卡支付)");
// 5. 未选择策略时支付(错误场景)
printf("\n========================================\n");
Order* empty_order = create_order(199.99f);
empty_order->pay_order(empty_order, "未选支付方式测试");
// 6. 销毁资源
printf("\n========================================\n");
order->destroy(order);
empty_order->destroy(empty_order);
return 0;
}
C语言实现关键要点
- 抽象策略接口(函数指针):
PaymentStrategy结构体通过pay函数指针定义统一支付接口,所有具体策略都实现该接口,确保上下文可通过统一方式调用不同算法。 - 策略实例化(全局静态变量):具体策略(支付宝、微信等)为全局静态结构体实例,无需动态分配内存,切换策略仅修改指针指向,效率高。
- 上下文持有策略指针:
Order的current_strategy指针指向当前策略,上下文不关心策略的具体实现,仅通过接口调用,实现解耦。 - 动态切换策略:上下文提供
set_strategy接口,客户端可在运行时灵活切换策略(如从支付宝切换到微信),无需修改上下文代码。 - 消除条件判断:客户端无需用
if-else判断选择哪种支付方式,直接通过切换策略指针实现,代码更简洁、可维护。 - 扩展性:新增支付方式(如Apple Pay)时,仅需定义新的
PaymentStrategy实例并实现pay函数,客户端直接切换即可,无需修改上下文和其他策略,符合“开闭原则”。 - 内存管理:策略为全局静态变量(生命周期贯穿程序),上下文手动
malloc/free,避免内存泄漏;策略切换无额外内存开销。
C++实现(类+继承+多态+智能指针)
C++通过“抽象基类+继承”定义策略接口,利用多态实现算法的动态分发,上下文持有抽象策略的智能指针,支持策略的动态切换和自动内存管理,代码更符合面向对象风格。
场景示例
同C语言:订单支付系统,抽象策略基类PaymentStrategy定义支付接口,具体策略子类实现不同支付逻辑,上下文Order通过多态调用策略。
实现代码
#include <iostream>
#include <string>
#include <memory> // 智能指针(自动管理内存)
using namespace std;
// -------------------------- 1. 抽象策略(PaymentStrategy):抽象基类 --------------------------
class PaymentStrategy {
public:
virtual ~PaymentStrategy() = default; // 虚析构:确保子类析构被调用
// 纯虚函数:统一支付接口(算法核心)
virtual bool pay(float amount, const string& remark) const = 0;
// 获取策略名称(用于日志)
virtual string getName() const = 0;
};
// -------------------------- 2. 具体策略类(不同支付方式) --------------------------
// 具体策略1:支付宝支付
class AlipayPay : public PaymentStrategy {
public:
bool pay(float amount, const string& remark) const override {
cout << "\n=== 【" << getName() << "】 ===" << endl;
cout << "支付金额:" << fixed << setprecision(2) << amount << " 元" << endl;
cout << "备注:" << remark << endl;
cout << "执行支付宝支付逻辑(调用支付宝SDK、验证签名...)" << endl;
cout << "支付宝支付成功!" << endl;
return true;
}
string getName() const override {
return "支付宝支付";
}
};
// 具体策略2:微信支付
class WechatPay : public PaymentStrategy {
public:
bool pay(float amount, const string& remark) const override {
cout << "\n=== 【" << getName() << "】 ===" << endl;
cout << "支付金额:" << fixed << setprecision(2) << amount << " 元" << endl;
cout << "备注:" << remark << endl;
cout << "执行微信支付逻辑(调用微信SDK、验证openid...)" << endl;
cout << "微信支付成功!" << endl;
return true;
}
string getName() const override {
return "微信支付";
}
};
// 具体策略3:银行卡支付
class BankCardPay : public PaymentStrategy {
public:
bool pay(float amount, const string& remark) const override {
cout << "\n=== 【" << getName() << "】 ===" << endl;
cout << "支付金额:" << fixed << setprecision(2) << amount << " 元" << endl;
cout << "备注:" << remark << endl;
cout << "执行银行卡支付逻辑(验证卡号、密码、短信验证码...)" << endl;
cout << "银行卡支付成功!" << endl;
return true;
}
string getName() const override {
return "银行卡支付";
}
};
// -------------------------- 3. 上下文(Order):使用策略的客户端 --------------------------
class Order {
public:
// 构造函数:初始化订单金额,默认无策略
Order(float amount) : amount_(amount), strategy_(nullptr) {
cout << "创建订单成功,金额:" << fixed << setprecision(2) << amount_ << " 元" << endl;
}
// 切换策略(智能指针管理策略对象,自动销毁旧策略)
void setStrategy(unique_ptr<PaymentStrategy> strategy) {
if (!strategy) {
cout << "错误:支付策略不能为空!" << endl;
return;
}
strategy_ = move(strategy); // 转移智能指针所有权
cout << "已切换支付方式为:" << strategy_->getName() << endl;
}
// 执行支付(多态调用策略的pay方法)
bool payOrder(const string& remark) const {
if (!strategy_) {
cout << "错误:未选择支付方式!" << endl;
return false;
}
cout << "订单开始支付,金额:" << fixed << setprecision(2) << amount_ << " 元" << endl;
return strategy_->pay(amount_, remark); // 多态分发:调用具体策略的支付逻辑
}
private:
float amount_; // 订单金额(上下文数据)
unique_ptr<PaymentStrategy> strategy_; // 持有当前策略(智能指针自动管理内存)
};
// -------------------------- 测试代码(客户端) --------------------------
int main() {
// 1. 创建订单(上下文)
Order order(299.99f);
cout << "========================================\n";
// 2. 选择支付宝支付(切换策略1)
order.setStrategy(make_unique<AlipayPay>());
order.payOrder("购买电子产品");
// 3. 切换为微信支付(切换策略2)
cout << "\n========================================\n";
order.setStrategy(make_unique<WechatPay>());
order.payOrder("购买电子产品(微信补付)");
// 4. 切换为银行卡支付(切换策略3)
cout << "\n========================================\n";
order.setStrategy(make_unique<BankCardPay>());
order.payOrder("购买电子产品(银行卡支付)");
// 5. 未选择策略时支付(错误场景)
cout << "\n========================================\n";
Order empty_order(199.99f);
empty_order.payOrder("未选支付方式测试");
return 0; // 智能指针自动销毁策略和订单对象,无需手动释放
}
C++实现关键要点
- 抽象基类+多态:
PaymentStrategy定义纯虚函数pay和getName,具体策略子类继承并实现,上下文通过基类指针(智能指针)调用,实现多态分发,解耦上下文与具体策略。 - 智能指针管理内存:上下文用
unique_ptr持有策略对象,自动创建和销毁策略,避免内存泄漏;move语义转移策略所有权,切换策略时自动释放旧策略。 - 动态切换策略:上下文提供
setStrategy方法,客户端通过make_unique创建具体策略并传递,切换过程简洁高效,无需手动管理策略生命周期。 - 封装性强:策略的具体实现(如支付SDK调用、签名验证)隐藏在子类中,上下文仅依赖抽象基类,不关心具体实现,符合“依赖倒置原则”。
- 扩展性极佳:新增支付方式(如Apple Pay)时,仅需创建新的子类继承
PaymentStrategy并实现纯虚函数,客户端调用setStrategy切换即可,无需修改上下文和其他策略,完全符合“开闭原则”。 - 类型安全:C++的编译期类型检查和多态机制,避免C语言中函数指针绑定错误或类型转换风险,代码更可靠;虚析构函数确保子类析构被正确调用。
策略模式核心总结(C vs C++)
| 对比维度 | C语言实现 | C++语言实现 |
|---|---|---|
| 接口定义 | 结构体+函数指针 | 抽象基类+纯虚函数(多态) |
| 内存管理 | 全局静态策略实例+上下文手动malloc/free | 智能指针(unique_ptr)自动管理,RAII原则 |
| 策略切换 | 直接修改上下文的策略指针 | 调用setStrategy方法,转移智能指针所有权 |
| 类型安全 | 依赖手动指针操作,风险高 | 编译期类型检查+多态,类型安全 |
| 封装性 | 策略实现与接口在同一结构体,封装性一般 | 策略实现隐藏在子类中,私有成员不可访问,封装性强 |
| 扩展性 | 新增策略需定义结构体+函数指针,手动绑定 | 新增策略仅需继承抽象基类,实现纯虚函数 |
| 代码可读性 | 函数指针和全局实例,可读性一般 | 类继承结构清晰,多态调用直观,可读性强 |
通用关键要点(跨语言)
设计原则:
- 开闭原则:新增/修改算法仅需调整策略类,无需修改上下文和客户端;
- 依赖倒置原则:上下文依赖策略抽象,不依赖具体策略实现;
- 单一职责原则:每个策略类仅负责自身的算法逻辑,上下文仅负责策略管理和调用。
582

被折叠的 条评论
为什么被折叠?



