C++ 策略模式

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

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

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

一、模式动机

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

  • 避免条件分支冗余
    替代if-elseswitch-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. 运行时动态切换算法

都很适合用策略模式。

相关推荐
青山是哪个青山4 小时前
LangChain 学习笔记(四):Message 与提示词模板
笔记·学习·langchain
Shell运维手记7 小时前
Linux 常用基础命令学习笔记
linux·运维·笔记·学习·算法·github
FakeOccupational8 小时前
【电路笔记 STM32】Cortex-M7 内核上的数据缓存(D-Cache)结构+MPU+DMA&Cache+STM32CubeMX配置
笔记·stm32·缓存
动词ing8 小时前
【学习笔记】C语言(数组指针与指针数组+字符数组+函数+参数传递+字符串作为形参+递归函数+指针函数+回调函数+结构体嵌套+内存动态分配函数)
c语言·笔记·学习
z落落10 小时前
C# Modbus-ASCII 超详细完整笔记(协议原理+LRC算法+读写源码全拆解)
笔记
hanlin0313 小时前
刷题笔记:力扣第189题-轮转数组
笔记·算法·leetcode
xqqxqxxq13 小时前
Redis 五大常用数据类型 + 通用命令笔记
数据库·redis·笔记
zjnlswd13 小时前
c# 刘铁猛 学习笔记
笔记·学习
LuminousCPP13 小时前
单链表专题(三)-刷题复盘篇:从快慢指针到环形链表 II 数学推导
数据结构·经验分享·笔记·学习·算法·链表
3A Cloud14 小时前
从「心即理」到提示词工程:深度解析 ClawHub 上的阳明心学技能(yangming-xinxue)
人工智能·笔记