设计模式 策略模式(Strategy Pattern) C++表达

设计模式 策略模式(Strategy Pattern) C++表达

flyfish

策略模式(Strategy Pattern)是一种行为设计模式,它的核心思想是将一系列相关的算法或行为封装到独立的策略类中,并使得这些策略可以相互替换。主要用来定义一系列可互换的算法或行为。它允许在运行时选择和切换这些算法或行为,而不用修改使用它们的代码。

策略模式就像给的代码提供了一组不同的工具,每个工具都可以完成相似的工作(例如不同的送货方式)。可以根据需要随时更换这些工具,而不需要修改太多代码。

举个例子

想象一下,有一家快递公司,提供了不同的送货方式:比如通过快递车、无人机或自行车送货。每种送货方式都有不同的优缺点和适用场景。希望可以根据具体情况选择最合适的送货方式。

如何实现?

  1. 定义策略接口 :首先,定义一个公共接口,比如 DeliveryMethod,里面有一个 deliver 方法,所有具体的送货方式都要实现这个方法。
cpp 复制代码
class DeliveryMethod {
public:
    virtual void deliver() const = 0; // 定义送货方法
    virtual ~DeliveryMethod() = default; // 虚析构函数
};
  1. 实现具体策略 :然后,为每种送货方式实现这个接口,比如 TruckDeliveryDroneDeliveryBikeDelivery
cpp 复制代码
class TruckDelivery : public DeliveryMethod {
public:
    void deliver() const override {
        std::cout << "Delivering by truck." << std::endl;
    }
};

class DroneDelivery : public DeliveryMethod {
public:
    void deliver() const override {
        std::cout << "Delivering by drone." << std::endl;
    }
};

class BikeDelivery : public DeliveryMethod {
public:
    void deliver() const override {
        std::cout << "Delivering by bike." << std::endl;
    }
};
  1. 上下文类 :然后,有一个上下文类 DeliveryContext,它包含一个 DeliveryMethod 的对象,并在需要的时候调用 deliver 方法。这个上下文类可以动态地更换送货方式。
cpp 复制代码
class DeliveryContext {
private:
    std::shared_ptr<DeliveryMethod> deliveryMethod; // 存储送货方法的指针
public:
    void setDeliveryMethod(std::shared_ptr<DeliveryMethod> method) {
        deliveryMethod = method;
    }

    void executeDelivery() const {
        if (deliveryMethod) {
            deliveryMethod->deliver();
        }
    }
};
  1. 使用策略模式 :在 main 函数中,可以创建不同的送货方式,并根据情况切换它们。
cpp 复制代码
int main() {
    DeliveryContext context;

    // 设置并执行卡车送货
    context.setDeliveryMethod(std::make_shared<TruckDelivery>());
    context.executeDelivery();

    // 设置并执行无人机送货
    context.setDeliveryMethod(std::make_shared<DroneDelivery>());
    context.executeDelivery();

    // 设置并执行自行车送货
    context.setDeliveryMethod(std::make_shared<BikeDelivery>());
    context.executeDelivery();

    return 0;
}

完整示例:

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

// 策略接口类
class DeliveryMethod {
public:
    virtual void deliver() const = 0; // 定义送货方法
    virtual ~DeliveryMethod() = default; // 虚析构函数
};

// 具体策略A类 - 卡车送货
class TruckDelivery : public DeliveryMethod {
public:
    void deliver() const override {
        std::cout << "Delivering by truck." << std::endl;
    }
};

// 具体策略B类 - 无人机送货
class DroneDelivery : public DeliveryMethod {
public:
    void deliver() const override {
        std::cout << "Delivering by drone." << std::endl;
    }
};

// 具体策略C类 - 自行车送货
class BikeDelivery : public DeliveryMethod {
public:
    void deliver() const override {
        std::cout << "Delivering by bike." << std::endl;
    }
};

// 上下文类
class DeliveryContext {
private:
    std::shared_ptr<DeliveryMethod> deliveryMethod; // 存储送货方法的指针

public:
    // 设置策略方法
    void setDeliveryMethod(std::shared_ptr<DeliveryMethod> method) {
        deliveryMethod = method;
    }

    // 执行策略方法
    void executeDelivery() const {
        if (deliveryMethod) {
            deliveryMethod->deliver();
        }
    }
};

int main() {
    DeliveryContext context; // 创建上下文对象

    // 设置并执行卡车送货
    context.setDeliveryMethod(std::make_shared<TruckDelivery>());
    context.executeDelivery();

    // 设置并执行无人机送货
    context.setDeliveryMethod(std::make_shared<DroneDelivery>());
    context.executeDelivery();

    // 设置并执行自行车送货
    context.setDeliveryMethod(std::make_shared<BikeDelivery>());
    context.executeDelivery();

    return 0;
}

策略模式还是这样写

  1. 使用 shared_ptr :允许多个上下文对象共享同一个策略对象,节省内存。
  2. 策略工厂和注册机制 :使用 StrategyFactory 类进行策略的注册和创建,支持动态添加新策略,并避免重复创建策略对象。
  3. 简化策略设置 :通过策略名称字符串来设置策略。
cpp 复制代码
#include <iostream>
#include <memory>
#include <unordered_map>
#include <functional>

// 策略接口类
class Strategy {
public:
    virtual ~Strategy() = default; // 虚析构函数,确保派生类对象可以被正确销毁
    virtual void execute() const = 0; // 纯虚函数,定义了算法的接口
};

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

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

// 策略工厂类
class StrategyFactory {
public:
    using CreateStrategyFn = std::function<std::shared_ptr<Strategy>()>;

    static StrategyFactory& instance() {
        static StrategyFactory factory;
        return factory;
    }

    void registerStrategy(const std::string& name, CreateStrategyFn createFn) {
        strategyMap_[name] = createFn;
    }

    std::shared_ptr<Strategy> getStrategy(const std::string& name) {
        auto it = strategyMap_.find(name);
        if (it != strategyMap_.end()) {
            return it->second();
        }
        return nullptr;
    }

private:
    std::unordered_map<std::string, CreateStrategyFn> strategyMap_;
};

// 上下文类
class Context {
private:
    std::shared_ptr<Strategy> strategy_; // 存储策略对象的智能指针

public:
    // 设置策略方法
    void setStrategy(const std::string& strategyName) {
        strategy_ = StrategyFactory::instance().getStrategy(strategyName);
    }

    // 执行策略方法
    void executeStrategy() const {
        if (strategy_) {
            strategy_->execute(); // 调用当前策略的执行方法
        }
    }
};

int main() {
    // 注册策略
    StrategyFactory::instance().registerStrategy("A", []() { return std::make_shared<ConcreteStrategyA>(); });
    StrategyFactory::instance().registerStrategy("B", []() { return std::make_shared<ConcreteStrategyB>(); });

    Context context; // 创建上下文对象

    // 设置并执行策略A
    context.setStrategy("A");
    context.executeStrategy();

    // 设置并执行策略B
    context.setStrategy("B");
    context.executeStrategy();

    return 0;
}
相关推荐
原来是猿19 分钟前
蓝桥备赛(四)- 数组(下)
开发语言·数据结构·c++·算法
zjkzjk771120 分钟前
reallocate() 和 allocate() 的区别
c++
星霜旅人1 小时前
【C++】深入理解List:双向链表的应用
c++
刀客1231 小时前
C++ STL(三)list
开发语言·c++
-拟墨画扇-1 小时前
C++ | 面向对象 | 类
c++·深拷贝··静态成员·友元函数·类拷贝构造函数·类构造析构函数
阿巴~阿巴~1 小时前
关于回溯算法中的剪枝是否需要for循环的总结归纳
数据结构·c++·算法·深度优先·剪枝
朔北之忘 Clancy1 小时前
2022 年 12 月青少年软编等考 C 语言五级真题解析
c语言·开发语言·c++·学习·算法·青少年编程·题解
千里码!2 小时前
java23种设计模式-模板方法模式
java·设计模式·模板方法模式
CoderCodingNo2 小时前
【GESP】C++二级模拟 luogu-b3995, [GESP 二级模拟] 小洛的田字矩阵
开发语言·c++·矩阵
kk\n2 小时前
C++ 红黑树万字详解(含模拟实现(两种版本))
数据结构·c++