策略模式及优化

策略模式(Strategy Pattern)是一种行为设计模式,其核心思想是将算法的定义与使用分离,使算法可以独立于客户端进行变化。它通过定义一系列算法,将每个算法封装到独立的类中,并使它们可以互相替换,从而让算法的变化不会影响到使用算法的客户端。

介绍

策略模式的核心组件
  1. 策略接口(Strategy Interface)
    定义所有具体策略必须实现的公共方法,通常是一个抽象类或接口。例如,在排序场景中,策略接口可能定义sort()方法。

  2. 具体策略(Concrete Strategies)
    实现策略接口的具体算法类。例如:BubbleSortQuickSortMergeSort等。

  3. 上下文(Context)
    持有一个策略接口的引用,负责根据需要动态切换具体策略。上下文不直接实现算法,而是将工作委托给策略对象。

  4. 客户端(Client)
    负责创建具体策略并将其注入到上下文中,控制策略的选择逻辑。

策略模式的特点
  1. 可替换性
    客户端可以在运行时动态切换策略,无需修改上下文代码。

  2. 开闭原则
    新增策略只需实现接口,无需修改现有代码,符合“对扩展开放,对修改关闭”的原则。

  3. 解耦算法
    算法的实现细节被封装在具体策略中,客户端无需关心其内部逻辑。

  4. 消除条件语句
    避免使用大量if-elseswitch语句来选择算法,使代码更简洁。

适用场景
  1. 多种算法选择:当一个问题有多种解决算法,且需要在运行时动态切换时。
  2. 避免条件语句:替代大量的if-elseswitch语句,使代码更清晰。
  3. 算法封装:将算法的实现细节与使用算法的客户端代码分离。

实现

#include <iostream>
#include <memory>
#include <string>// 策略接口:定义算法族
class SortStrategy {
public:virtual ~SortStrategy() = default;virtual void sort(std::vector<int>& data) const = 0;
};// 具体策略:冒泡排序
class BubbleSort : public SortStrategy {
public:void sort(std::vector<int>& data) const override {std::cout << "使用冒泡排序..." << std::endl;// 冒泡排序实现int n = data.size();for (int i = 0; i < n - 1; ++i) {for (int j = 0; j < n - i - 1; ++j) {if (data[j] > data[j + 1]) {std::swap(data[j], data[j + 1]);}}}}
};// 具体策略:快速排序
class QuickSort : public SortStrategy {
public:void sort(std::vector<int>& data) const override {std::cout << "使用快速排序..." << std::endl;// 快速排序实现quickSort(data, 0, data.size() - 1);}private:void quickSort(std::vector<int>& data, int left, int right) const {if (left < right) {int pivotIndex = partition(data, left, right);quickSort(data, left, pivotIndex - 1);quickSort(data, pivotIndex + 1, right);}}int partition(std::vector<int>& data, int left, int right) const {int pivot = data[right];int i = left - 1;for (int j = left; j < right; ++j) {if (data[j] <= pivot) {++i;std::swap(data[i], data[j]);}}std::swap(data[i + 1], data[right]);return i + 1;}
};// 上下文:维护一个策略引用
class Sorter {
private:std::unique_ptr<SortStrategy> strategy;public:explicit Sorter(std::unique_ptr<SortStrategy> strategy): strategy(std::move(strategy)) {}void setStrategy(std::unique_ptr<SortStrategy> strategy) {this->strategy = std::move(strategy);}void performSort(std::vector<int>& data) const {if (strategy) {strategy->sort(data);} else {std::cout << "未设置排序策略" << std::endl;}}
};// 客户端代码
int main() {std::vector<int> data = {5, 4, 3, 2, 1};// 使用冒泡排序Sorter sorter(std::make_unique<BubbleSort>());sorter.performSort(data);for (int num : data) {std::cout << num << " ";}std::cout << std::endl;// 切换为快速排序data = {5, 4, 3, 2, 1};sorter.setStrategy(std::make_unique<QuickSort>());sorter.performSort(data);for (int num : data) {std::cout << num << " ";}std::cout << std::endl;return 0;
}
应用场景
  1. 排序算法切换:根据数据规模选择冒泡排序、快速排序等。
  2. 支付方式:电商系统中支持支付宝、微信、银行卡等多种支付方式。
  3. 压缩算法:文件压缩工具支持ZIP、RAR、7Z等不同压缩算法。
  4. 游戏AI:不同难度的敌人使用不同的行为策略。
  5. 加密算法:安全系统中动态选择加密方式(MD5、SHA-256等)。
策略模式与其他模式的对比
模式核心区别
策略模式算法的定义与使用分离,强调运行时动态切换。
状态模式行为随内部状态变化而变化,状态转换通常由上下文触发。
工厂模式专注于对象的创建,而不涉及对象的行为。

策略模式优化(注册机制和反射)

优化措施
  1. 策略工厂与注册机制

    • StrategyFactory 使用单例模式管理策略的创建
    • 通过 registerStrategy 方法注册策略名称和对应的工厂函数
    • StrategyRegistrar 模板类用于静态注册,避免手动调用注册函数
  2. 反射机制

    • 使用 std::function 和 lambda 表达式实现类型擦除
    • 通过字符串名称动态创建策略对象
    • 静态注册确保在程序初始化时完成所有策略的注册
  3. Sorter类改进

    • 在构造函数中初始化所有策略实例
    • 使用 std::unordered_map 管理策略对象
    • 通过 setStrategy 方法动态切换当前使用的策略
    • 所有策略对象仅创建一次,提高性能
#include <iostream>
#include <vector>
#include <memory>
#include <string>
#include <unordered_map>
#include <functional>// 策略接口
class SortStrategy {
public:virtual ~SortStrategy() = default;virtual void sort(std::vector<int>& data) const = 0;
};// 具体策略:冒泡排序
class BubbleSort : public SortStrategy {
public:void sort(std::vector<int>& data) const override {std::cout << "使用冒泡排序..." << std::endl;int n = data.size();for (int i = 0; i < n - 1; ++i) {for (int j = 0; j < n - i - 1; ++j) {if (data[j] > data[j + 1]) {std::swap(data[j], data[j + 1]);}}}}
};// 具体策略:快速排序
class QuickSort : public SortStrategy {
public:void sort(std::vector<int>& data) const override {std::cout << "使用快速排序..." << std::endl;quickSort(data, 0, data.size() - 1);}private:void quickSort(std::vector<int>& data, int left, int right) const {if (left < right) {int pivotIndex = partition(data, left, right);quickSort(data, left, pivotIndex - 1);quickSort(data, pivotIndex + 1, right);}}int partition(std::vector<int>& data, int left, int right) const {int pivot = data[right];int i = left - 1;for (int j = left; j < right; ++j) {if (data[j] <= pivot) {++i;std::swap(data[i], data[j]);}}std::swap(data[i + 1], data[right]);return i + 1;}
};// 策略工厂:负责创建策略实例
class StrategyFactory {
public:static StrategyFactory& getInstance() {static StrategyFactory instance;return instance;}void registerStrategy(const std::string& name, std::function<std::unique_ptr<SortStrategy>()> factory) {factories[name] = factory;}std::unique_ptr<SortStrategy> createStrategy(const std::string& name) {auto it = factories.find(name);if (it != factories.end()) {return it->second();}return nullptr;}private:StrategyFactory() = default;std::unordered_map<std::string, std::function<std::unique_ptr<SortStrategy>()>> factories;
};// 策略注册表:静态注册策略
template<typename T>
struct StrategyRegistrar {StrategyRegistrar(const std::string& name) {StrategyFactory::getInstance().registerStrategy(name, []() {return std::make_unique<T>();});}
};// 上下文:维护策略并提供排序功能
class Sorter {
public:Sorter() {strategies["bubble"] = StrategyFactory::getInstance().createStrategy("bubble");strategies["quick"] = StrategyFactory::getInstance().createStrategy("quick");currentStrategy = strategies["bubble"].get();}void setStrategy(const std::string& name) {auto it = strategies.find(name);if (it != strategies.end()) {currentStrategy = it->second.get();} else {std::cout << "未找到策略: " << name << std::endl;}}void performSort(std::vector<int>& data) const {if (currentStrategy) {currentStrategy->sort(data);} else {std::cout << "未设置排序策略" << std::endl;}}private:std::unordered_map<std::string, std::unique_ptr<SortStrategy>> strategies;SortStrategy* currentStrategy;
};// 静态注册策略
static StrategyRegistrar<BubbleSort> bubbleRegistrar("bubble");
static StrategyRegistrar<QuickSort> quickRegistrar("quick");// 客户端代码
int main() {std::vector<int> data = {5, 4, 3, 2, 1};Sorter sorter;// 使用冒泡排序sorter.setStrategy("bubble");sorter.performSort(data);for (int num : data) {std::cout << num << " ";}std::cout << std::endl;// 切换为快速排序data = {5, 4, 3, 2, 1};sorter.setStrategy("quick");sorter.performSort(data);for (int num : data) {std::cout << num << " ";}std::cout << std::endl;return 0;
}

添加新策略时,只需:

  1. 创建新的策略类,继承自 SortStrategy
  2. 实现 sort 方法
  3. 添加静态注册语句:
    static StrategyRegistrar<NewSortStrategy> newRegistrar("new");
    

// 无需修改 Sorter 类,完全符合开闭原则。
客户端通过字符串名称即可使用新策略,实现了对修改封闭,对扩展开放的设计目标。

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。
如若转载,请注明出处:http://www.pswp.cn/bicheng/89159.shtml
繁体地址,请注明出处:http://hk.pswp.cn/bicheng/89159.shtml

如若内容造成侵权/违法违规/事实不符,请联系多彩编程网进行投诉反馈email:809451989@qq.com,一经查实,立即删除!

相关文章

微信小程序开发-桌面端和移动端UI表现不一致问题记录

桌面端和移动端UI表现不一致零、引擎说明一、样式不同1、text 单行&#xff1a;1.1 空格开发者工具不展示&#xff0c;手机/PC端正常1.2 正常展示省略号&#xff0c;需要2、点击按钮z-index: -1。webview - 桌面端不行&#xff0c; skyline - 移动端可以&#xff1b;3、其他说明…

极限状态下函数开根号的计算理解(含示意图)

遇到一个挺有意思的题做个记录&#xff1a; 求曲线y (x21)(x2−1)0.5\frac{\left(x^{2}1\right)}{\left(x^{2}-1\right)^{0.5}}(x2−1)0.5(x21)​渐近线的条数 比较明显的x 1是无定义点。但是在求极限的时候发现1和1-得到的极限值似乎不一样。似乎是1是趋向于∞&#xff0c;1…

C++——模版(函数模版和类模版)

C 模板&#xff08;Templates&#xff09;完整介绍模板是 C 中一种强大的泛型编程机制&#xff0c;允许开发者编写与类型无关的代码&#xff0c;从而提高代码的复用性和灵活性。通过模板&#xff0c;可以避免为不同数据类型重复编写相似的函数或类&#xff0c;实现真正的代码复…

Python之cv2:cv2(OpenCV,opencv-python)库pip下载超时、下载失败、无法下载的解决方案大全

Python之cv2&#xff1a;cv2(OpenCV&#xff0c;opencv-python)库pip下载超时、下载失败、无法下载的解决方案大全 在学习和使用 OpenCV&#xff08;Python 包名&#xff1a;opencv-python 或简称 cv2&#xff09;的过程中&#xff0c;很多初学者常常会遇到通过 pip install o…

asyncio 与 uvloop

事件循环 事件循环 协调所有协程执行的中央调度器&#xff0c;它通过非阻塞机制&#xff0c;实现并发执行多个异步任务。 事件循环是 异步编程的核心机制&#xff0c;用一句话概括就是&#xff1a; 事件循环不断检查任务队列&#xff0c;一旦某个异步任务完成&#xff0c;它…

一文读懂循环神经网络(RNN)—语言模型+n元语法(1)

目录 什么是语言模型&#xff1f; 语言模型的核心目的 一.量化文本的合理性 二.支持下游 NLP 任务 三. 语义和上下文依赖 一元语法、二元语法和三元语法详解 核心概念&#xff1a;n-gram 模型 1. 一元语法&#xff08;Unigram&#xff09; 2. 二元语法&#xff08;Bigram…

DirectX12(D3D12)基础教程九 间接绘制

在学习directx12 microsoft提供了很多示例&#xff0c;有简单的也有复杂,下载网址&#xff1a;https://github.com/microsoft/DirectX-Graphics-Samples 本章对D3D12ExecuteIndirect 示例做了简化&#xff0c;只保留间接绘制部分&#xff0c;删除了计算着色器部分。 间接绘制…

fastApi连接数据库

1&#xff1a;pip install tortoise-orm2&#xff1a;pip install aiomysql3&#xff1a;pip install asyncmy或者使用国内清华园pip install -i https://pypi.tuna.tsinghua.edu.cn/simple asyncmy4&#xff1a;pip install aerich通过 python -m 直接运行&#xff08;推荐&a…

Apache-web服务器环境搭建

目录 实验要求 思路总结 1.常规配置web服务 2.通过用户主页配置web服务 3.通过虚拟目录配置web服务 4.添加DNS解析服务&#xff0c;访问虚拟机域名&#xff1a; www.TestWeb.com 实验要求 (ip 192.168.48.130) 1、常规配置web服务 2、通过用户主页配置web服务 3、通过虚…

Altium Designer 25 安装与配置完整教程

本教程将带您一步步完成 Altium Designer 25 的下载、安装与激活配置 第一步&#xff1a;下载安装包 首先&#xff0c;需要获取 Altium Designer 25 的完整安装程序。 &#x1f449; 下载链接&#xff1a; 百度网盘&#xff1a;百度网盘 请输入提取码 提取码: dxei 夸克网盘…

【工具】AndroidStudio修改中文语言汉化

AndroidStudio修改中文语言汉化 https://github.com/sollyu/AndroidStudioChineseLanguagePackhttps://github.com/sollyu/AndroidStudioChineseLanguagePack

代码随想录|图论|15并查集理论基础

并查集理论基础 | 代码随想录 并查集还是比较简单的&#xff0c;只要搞清楚两个事情&#xff1a; 并查集是干啥的&#xff1f;解决什么类型问题&#xff1f;并查集模板&#xff08;背下来&#xff09; 1、并查集是干啥的 并查集主要是两个功能&#xff1a; 两个元素添加到…

用MYSQL学习sql第一次总结和作业

总结 数据库&#xff08;Database&#xff09; 理解为“文件夹”&#xff0c;里面可以装很多张表。作业中要求先建一个名字叫 mydb6_product 的数据库。 表&#xff08;Table&#xff09; 理解为“Excel 工作表”&#xff0c;由“列&#xff08;字段&#xff09;”和“行&…

SQLite技术架构解析,适用场景有哪些?

一、SQLite技术架构解析 SQLite是一款轻量级、无服务器、嵌入式关系型数据库&#xff0c;其架构设计围绕“简化复杂性、提升效率”展开&#xff0c;核心由前端&#xff08;SQL处理&#xff09;、执行引擎&#xff08;VDBE&#xff09;、存储引擎&#xff08;B-Tree&#xff09;…

【Luogu】每日一题——Day3. P6392 中意 (数学 取模)

链接&#xff1a;P6392 中意 - 洛谷 题目&#xff1a; 思路&#xff1a; 数论这一块 题目让我们求这个结果对 MOD 取模&#xff0c;那么我们肯定是不像看到这个除法&#xff0c;所以考虑如何消除这个除法 我们可以想到&#xff0c;向上取整就是加上一个数&#xff0c;假设其为…

React强大且灵活hooks库——ahooks入门实践之DOM类hook(dom)详解

什么是 ahooks&#xff1f; ahooks 是一个 React Hooks 库&#xff0c;提供了大量实用的自定义 hooks&#xff0c;帮助开发者更高效地构建 React 应用。其中 DOM 类 hooks 是 ahooks 的一个重要分类&#xff0c;专门用于处理 DOM 相关操作&#xff0c;如事件监听、元素状态、拖…

GeoTools 工厂设计模式

前言使用GeoTools开发时有必要了解其工厂设计模式&#xff0c;作为软件开发核心设计模式&#xff0c;其设计思想具有普遍性和研究性。明白方法原理有助于提高开发效率&#xff0c;达到事半功倍的效果。1. 工厂模式 工厂模式&#xff08;Factory Pattern&#xff09;是面向对象中…

npu-smi info命令参数解释

华为昇腾npu-smi显示npu-smi工具的帮助信息npu-smi -h字段说明-h命令的帮助信息–help命令的帮助信息-vnpu-smi版本信息info显示硬件详细信息set修改设备配置属性clear清除设备信息upgrade升级MCU固件 npu-smi info 用于监控和管理华为NPU的状态和性能字段值说明npu-smi24.1.rc…

OneCode3.0 通信架构简介——MCPServer微内核设计哲学与实现

在数字化转型加速的今天&#xff0c;低代码平台已成为企业快速交付应用的核心基础设施。然而&#xff0c;通用消息中间件与低代码开发范式之间存在难以调和的矛盾&#xff1a;标准化协议无法匹配可视化编排的动态性&#xff0c;通用架构难以满足低代码场景下高频短消息的性能需…

Android14 Launcher3 修改All App上下滑动头部显示阴影

正常情况下的样子&#xff1a; 下拉App抽屉后的样子&#xff1a;修改方案&#xff1a;qssi14/packages/apps/Launcher3/src/com/android/launcher3/allapps/ActivityAllAppsContainerView.javaprotected void updateHeaderScroll(int scrolledOffset) {float prog1 Utilities…