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. 运行时动态切换算法

都很适合用策略模式。

相关推荐
小小的代码里面挖呀挖呀挖2 小时前
恒玄BES蓝牙耳机开发--IIC接口应用
笔记·单片机·物联网·学习·iot
abel0042 小时前
《纳瓦尔宝典》笔记
笔记
wb1892 小时前
企业级MySQL重习
数据库·笔记·mysql·adb·云计算
tswowo62 小时前
Markdown笔记
笔记
海兰3 小时前
【springboot】gradle快速镜像配置
spring boot·笔记·后端
weixin_432444763 小时前
单片机 Flash 指定地址存储常量字符串调试笔记
笔记·单片机·嵌入式硬件
飞鸟真人3 小时前
关于能所合一豆包问答笔记
笔记
wb1893 小时前
docker-ce容器技术重习
运维·笔记·docker·容器·云计算
咖啡忍者3 小时前
【SAP CO】4.COPC产品成本控制-5.生产订单
笔记