C++ 策略模式

借鉴:https://blog.csdn.net/Xiluo_pro/article/details/157728687

策略模式(Strategy Pattern) 是一种行为型设计模式。

策略模式的主要目的是通过封装算法和动态切换策略,实现代码的灵活性和可维护性。

一、模式动机

策略模式旨在解决以下问题:

  • 避免条件分支冗余
    替代if-else或switch-case判断,通过多态动态选择算法,减少代码耦合。
  • 支持算法动态切换
    运行时根据需求更换具体策略(如支付方式、排序规则),无需修改上下文类代码。
  • 符合开闭原则
    新增策略时只需扩展具体策略类,无需修改现有代码,降低维护成本。
cpp 复制代码
void func(int tpye){
    if (type == A) { ... }
    else if (type == B) { ... }
    else if (type == C) { ... }
}
 
/*
说明:
 
算法逻辑与业务逻辑耦合严重
 
新增一种算法需要修改原有代码
 
违反 开闭原则(OCP)
*/

👉 策略模式:

把不同算法抽象成"策略对象",由外部决定使用哪一种。

二、关键实现机制

策略模式包含 3 个核心角色:

  1. Strategy(抽象策略)

    定义算法接口

  2. ConcreteStrategy(具体策略)

    实现具体算法

  3. Context(上下文)

    持有策略对象,调用其算法

关键实现机制(策略模式=多态+上下文环境类)

  • 多态
    通过抽象策略接口(如PaymentStrategy)统一调用方法,具体实现(如AlipayStrategy)在运行时动态绑定。
  • 上下文环境类
    封装策略切换逻辑(如OrderProcessor.setStrategy()),客户端只需与上下文交互,无需直接依赖具体策略。

有同学会问,多态就够了呀为什么还需要上下文环境类?解答如下:

  1. 上下文类的核心作用
    上下文类(Context)是策略模式的关键组件,它负责:

    • 解耦客户端与策略实现:客户端只需选择策略,无需直接调用具体算法。
    • 封装复杂逻辑:如线程池的拒绝策略、资源管理等,由上下文统一处理。
    • 提供统一接口:客户端无论使用何种策略,调用方式始终一致。
  2. 不使用上下文类的后果

    • 耦合度增加:客户端直接依赖具体策略类,修改算法时需同时修改客户端代码(违反开闭原则)。
    • 代码重复 :多个客户端需重复实现策略调用逻辑(如if-else分支)。
    • 可扩展性降低:新增策略时需遍历所有客户端代码进行修改。
  3. 何时可以省略上下文类

    仅当满足以下条件时,可考虑省略上下文类:

    • 算法极其简单 :如加减乘除,可直接用多态或函数式编程(Java 8+的Lambda)。
    • 无复杂逻辑:策略调用无需额外处理(如资源管理、状态同步)。
    • 客户端数量少:且策略变化频率低,硬编码成本可接受。

三、C++ 示例

cpp 复制代码
//抽象策略
class SortStrategy {
public:
    virtual ~SortStrategy() {}
    virtual void sort(std::vector<int>& data) = 0;
};
 
//具体策略
class BubbleSort : public SortStrategy {
public:
    void sort(std::vector<int>& data) override {
        // 冒泡排序
    }
};
 
class QuickSort : public SortStrategy {
public:
    void sort(std::vector<int>& data) override {
        // 快速排序
    }
};
 
//上下文
class SortContext {
public:
    void setStrategy(SortStrategy* s) {
        strategy = s;
    }
 
    void execute(std::vector<int>& data) {
        if (strategy)
            strategy->sort(data);
    }
 
private:
    SortStrategy* strategy = nullptr;
};
 
int main() {
    std::vector<int> v = {5, 2, 8, 1};
 
    BubbleSort bubble;
    QuickSort quick;
 
    SortContext ctx;
 
    ctx.setStrategy(&bubble);
    ctx.execute(v);   // 使用冒泡排序
 
    ctx.setStrategy(&quick);
    ctx.execute(v);   // 切换为快速排序
}

四、典型应用场景

  1. 多种算法可互换

    • 排序方式

    • 压缩算法(zip、rar、7z)

    • 加密算法(AES、RSA、MD5)

  2. 避免大量 if-else / switch-case

  3. 运行时动态切换算法

都很适合用策略模式。

相关推荐
sbjdhjd6 小时前
网工进阶笔记:H3CSE 园区网全栈技术与协议汇总
网络·笔记·云计算·ssh·网络工程·vlan·aaa
海绵宝宝的月光宝盒9 小时前
14-AutoCAD-阵列命令应用与案例实战(AR)
经验分享·笔记·自动化·课程设计·制造·学习方法·cad
白山编程大哥10 小时前
接口幂等性是什么?如何设计?
笔记
ACP广源盛1392462567310 小时前
6 盘位存储扩展方案选型笔记:YLB3116 @ACP评估记录
笔记·硬件架构·硬件工程·国产芯片
小李不想当小白11 小时前
SPI通信外设与W25Q64 (硬件SPI)(STM32标准库学习笔记)
笔记·stm32·单片机·嵌入式硬件·学习·嵌入式
weixin_4481199413 小时前
Datawhale Jev Cookbook 202610 笔记3
笔记
姚瑞南13 小时前
【PRD】招投标商机雷达爬虫系统
人工智能·经验分享·笔记·爬虫·产品运营·产品经理
Gnevergiveup13 小时前
ATT&CK红蓝对抗实战指南-Windows安全基础
笔记·网络安全
江屿风16 小时前
【Plain Language Large Model】【从麦当劳点餐到Redis接入:MCP如何让AI工具集成变简单】流食般投喂
人工智能·redis·笔记·语言模型·llm·mcp
海绵宝宝转agent17 小时前
Leetcode二叉树算法个人理解
笔记·学习·算法·leetcode·深度优先