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

ops/2024/9/23 11:20:54/

Strategy_Pattern_C_0">设计模式 策略模式Strategy Pattern) C++表达

flyfish

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

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

举个例子

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

如何实现?

  1. 定义策略接口 :首先,定义一个公共接口,比如 DeliveryMethod,里面有一个 deliver 方法,所有具体的送货方式都要实现这个方法。
class DeliveryMethod {
public:virtual void deliver() const = 0; // 定义送货方法virtual ~DeliveryMethod() = default; // 虚析构函数
};
  1. 实现具体策略 :然后,为每种送货方式实现这个接口,比如 TruckDeliveryDroneDeliveryBikeDelivery
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 方法。这个上下文类可以动态地更换送货方式。
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 函数中,可以创建不同的送货方式,并根据情况切换它们。
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;
}

完整示例:

#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. 简化策略设置 :通过策略名称字符串来设置策略。
#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; // 创建上下文对象// 设置并执行策略Acontext.setStrategy("A");context.executeStrategy();// 设置并执行策略Bcontext.setStrategy("B");context.executeStrategy();return 0;
}

http://www.ppmy.cn/ops/89188.html

相关文章

文件系统 FTP Ubuntu 安装入门介绍

文件服务系列 文件存储服务系统&#xff08;File Storage Service System&#xff09;-00-文件服务器是什么&#xff1f;为什么需要&#xff1f; 文件存储服务系统&#xff08;File Storage Service System&#xff09;-01-常见的文件协议介绍 文件系统 FTP Ubuntu 安装入门…

QTableWidget的使用(可多行输入)

效果展示 源码 mainwindow.h #ifndef MAINWINDOW_H #define MAINWINDOW_H#include <QMainWindow>class QTableWidget; class MainWindow : public QWidget {Q_OBJECTpublic:MainWindow(QWidget *parent nullptr);~MainWindow();private:void insertTableRow(const QSt…

RabbitMQ 应用

目录 1. 7种工作模式 1.1 Simple&#xff08;简单模式&#xff09; 1.2 Work Queue&#xff08;工作队列&#xff09; 1.3 Publish/Subscribe&#xff08;发布/订阅&#xff09; 1.4 Routing&#xff08;路由模式&#xff09; 1.5 Topics&#xff08;通配符模式&#xff09; 1.…

【抖音短视频SEO矩阵,PHP开发实战揭秘!】

短视频SEO矩阵系统&#xff1a; 一款专业的PHP SaaS解决方案 短视频SEO矩阵系统是一款专为提升短视频在搜索引擎排名而设计的PHP SaaS源码解决方案。该系统致力于协助用户优化短视频内容&#xff0c;实现内容的高效分发&#xff0c;以便吸引更多目标观众。 它集成了全面的功能…

面向对象编程和面向过程编程

面向对象编程&#xff08;OOP&#xff09; 以对象为中心&#xff0c;将现实世界中的事物抽象为对象&#xff0c;通过对象之间的交互来解决问题。它强调将程序划分为一系列相互协作的对象&#xff0c;每个对象都有自己的属性和方法&#xff0c;分别代表对象的状态和行为 面向过…

Python开发程序中找到未排序数组中的第K大元素:高效算法与实现

Python开发程序中找到未排序数组中的第K大元素:高效算法与实现 在数据处理和算法设计中,寻找数组中的特定元素是一项常见的任务。特别是在未排序的数组中,找到第K大元素是一个经典问题,广泛应用于数据分析、统计学和机器学习等领域。本文将详细介绍如何实现一个函数,找到…

[windows][frp]在Windows上安装和配置FRP的服务器端(frps)和客户端(frpc)

在Windows上安装和配置FRP&#xff08;Fast Reverse Proxy&#xff09;的服务器端&#xff08;frps&#xff09;和客户端&#xff08;frpc&#xff09;通常涉及以下步骤&#xff1a; 1. 下载FRP 首先&#xff0c;您需要从FRP的GitHub页面下载适用于Windows的FRP二进制文件。访…

【SQL Server点滴积累】SQL Server 2016数据库邮件(Database Mail)功能故障的解决方法

广告位招租&#xff01; 知识无价&#xff0c;人有情&#xff0c;无偿分享知识&#xff0c;希望本条信息对你有用&#xff01; 今天和大家分享SQL Server 2016数据库邮件(Database Mail)功能故障的解决方法 故障现象&#xff1a; 在SQL Server 2016中配置完成数据库邮件(Dat…