策略模式的C++实现示例

核心思想

策略模式是一种行为型设计模式,它定义了一系列算法,并将每个算法封装在独立的类中,使得它们可以互相替换。策略模式让算法的变化独立于使用它的客户端,从而使得客户端可以根据需要动态切换算法,而不需要修改其代码。策略模式的核心是将算法与使用算法的客户端解耦,使得算法可以独立于客户端变化。

**Context:**持有一个策略对象的引用,负责调用策略的具体实现。

**Strategy:**定义所有支持的算法的公共接口。

**ConcreteStrategy:**实现Strategy接口,提供具体的算法实现。

使用场景

多种算法切换:如排序算法(快速排序、冒泡排序等)或支付方式(信用卡、支付宝等)。

避免条件语句:当代码中有大量条件分支用于选择不同行为时,可以用策略模式替代。

算法复用:当多个类需要共享相同的行为,但行为的具体实现不同时。

动态切换行为:如游戏中的角色在不同状态下使用不同的攻击策略。

测试与调试:策略模式可以方便地替换算法的实现,便于测试和调试。

解决的问题

代码重复问题:

如果多个类使用相同的算法,但算法的实现分散在各处,会导致代码重复。策略模式将算法集中管理,避免重复。

紧耦合问题:

在传统设计中,算法直接嵌入在客户端代码中,导致客户端与算法紧耦合。策略模式通过将算法抽象为接口,解耦了客户端和具体算法。

扩展性问题:

新增算法时,需要修改客户端代码。策略模式允许动态添加新算法,而无需修改现有代码。

条件分支问题:

当代码中有大量条件分支用于选择不同行为时,策略模式可以将其替换为对象的多态调用,使代码更清晰。

优点

**开闭原则:**新增算法无需修改现有代码,只需添加新的策略类。

**解耦:**将算法的实现与使用分离,提高代码的灵活性和可维护性。

**复用性:**策略类可以在不同上下文中复用。

**简化测试:**每个策略类可以独立测试。

缺点

**类数量增加:**每个算法都需要一个单独的类,可能导致类的数量增多。

**客户端需要了解策略:**客户端需要知道有哪些策略,并选择合适的策略。

**性能开销:**策略模式可能引入额外的对象创建和调用开销。

示例代码

如下代码中,Context类(即客户端)是稳定、可以不变的,变化的是策略,而策略是根据运行时的实际情况来选择的。通过继承Strategy类并重写execute()接口实现策略的扩展。

cpp 复制代码
#include <iostream>
#include <memory>

// 抽象策略接口
class Strategy {
public:
    virtual void execute() const = 0;
    virtual ~Strategy() = default;  // 虚析构函数,确保正确释放资源
};

// 具体策略A
class ConcreteStrategyA : public Strategy {
public:
    void execute() const override {
        std::cout << "执行策略A" << std::endl;
    }
};

// 具体策略B
class ConcreteStrategyB : public Strategy {
public:
    void execute() const override {
        std::cout << "执行策略B" << std::endl;
    }
};

// 上下文类,持有策略对象并调用其方法
class Context {
private:
    std::unique_ptr<Strategy> strategy;  // 使用智能指针管理策略对象

public:
    // 构造函数,允许传入策略对象
    Context(std::unique_ptr<Strategy> s) : strategy(std::move(s)) {}

    // 设置策略
    void setStrategy(std::unique_ptr<Strategy> s) {
        strategy = std::move(s);
    }

    // 执行策略
    void executeStrategy() const {
        if (strategy) {
            strategy->execute();
        } else {
            std::cout << "未设置策略" << std::endl;
        }
    }
};

int main() {
    // 创建上下文对象,并初始化为策略A
    Context context(std::make_unique<ConcreteStrategyA>());
    context.executeStrategy();  // 输出: 执行策略A

    // 动态切换到策略B
    context.setStrategy(std::make_unique<ConcreteStrategyB>());
    context.executeStrategy();  // 输出: 执行策略B

    return 0;
}

代码说明

​Strategy:抽象策略接口,定义了所有具体策略类必须实现的方法execute()。

​ConcreteStrategyA​ 和 ​ConcreteStrategyB:具体策略类,分别实现了不同的算法或行为。

​Context:上下文类,持有一个策略对象的引用,并提供了设置策略和执行策略的方法。

​智能指针:使用std::unique_ptr管理策略对象的生命周期,避免内存泄漏。

运行结果

bash 复制代码
执行策略A
执行策略B

总结

通过策略模式,我们可以将算法的实现与使用算法的环境解耦,使得算法可以独立于客户端代码进行扩展和修改。这种设计模式特别适用于需要动态切换算法的场景。

相关推荐
code_pgf6 小时前
C++11 / C++14 / C++17 / C++20 新特性总结
c++·c++20
魔力女仆6 小时前
分享一个 JS 鼠标跟随贪吃蛇背景库
开发语言·javascript·计算机外设
2401_894915537 小时前
GEO 搜索优化完整源码从零部署:环境配置、集群搭建全流程
开发语言·python·tcp/ip·算法·unity
麻瓜老宋8 小时前
AI开发C语言应用按步走,表达式计算器calc的第二十二步,分号赋值链式修复、TOKEN_ASSIGN
c语言·开发语言·atomcode
颜x小10 小时前
[C#] C++与c#语法对比
开发语言·c++·c#
weixin_4236521310 小时前
C#使用JObject
开发语言·c#
国科安芯10 小时前
FreeRTOS RISC-V 浮点上下文切换移植:在 IAR 工程中完整保存 FPU 寄存器
java·开发语言·单片机·嵌入式硬件·算法·系统架构·risc-v
汉克老师11 小时前
GESP2026年3月认证C++八级( 第三部分编程题(2、子图最短路)精讲
c++·最短路·floyd·gesp8级
霸道流氓气质11 小时前
Java中集成Smile 技术教程:从入门到工程实践
java·开发语言
BerrySen17812 小时前
迈向 Next-Gen Java:企业级高并发架构演进与大模型 Agent 落地深度实战
java·开发语言·架构