【C++ 设计模式】策略模式与简单工厂模式的结合

文章目录

  • 前言
  • 一、为什么需要策略模式+简单工厂模式
  • 二、策略模式+简单工厂模式实现原理
  • 三、UML图
  • 四、示例代码
  • 总结


前言

在软件设计中,常常会遇到需要根据不同情况选择不同算法或行为的情况。策略模式和简单工厂模式是两种常见的设计模式,它们分别解决了对象行为的抽象和对象创建的抽象问题。在某些情况下,将这两种模式结合起来可以更好地满足实际需求,提高代码的灵活性和可维护性。

策略模式与简单工厂模式的结合:

策略模式用于定义一系列算法,将每个算法封装到独立的类中,并使它们可以相互替换,从而使得算法可以独立于客户端而变化。简单工厂模式用于封装对象的创建过程,将对象的创建与客户端解耦。

将策略模式与简单工厂模式结合起来,可以使得在创建具体策略对象时更加灵活,同时保持了策略对象的封装性。通过简单工厂模式,我们可以根据客户端的需求动态创建不同的具体策略对象,而策略模式则确保了这些对象可以被客户端无缝地使用。


一、为什么需要策略模式+简单工厂模式

当我们面对需要根据不同情况选择不同算法或行为的情况时,策略模式是一个很好的选择。它允许我们将不同的算法封装成独立的类,并且可以在运行时灵活地切换这些算法,而不影响客户端代码。然而,单独使用策略模式时,我们需要在客户端代码中显式地创建具体策略对象,这可能导致代码变得复杂,尤其当需要根据不同条件选择不同的策略时。

这时候,简单工厂模式可以派上用场。简单工厂模式提供了一个统一的接口来创建对象,客户端只需提供简单的参数,而不必了解具体对象的创建过程。将策略模式与简单工厂模式结合起来,可以在需要时动态地创建不同的具体策略对象,同时保持代码的简洁和可维护性。简单工厂模式负责对象的创建,而策略模式确保了这些对象可以被灵活地使用,让我们的软件更加智能和适应变化。这种结合使用的设计模式能够提高代码的灵活性、可扩展性和可维护性,使得软件系统更加健壮和易于理解。

二、策略模式+简单工厂模式实现原理

  • 策略模式:

首先定义一个策略接口(或抽象类),其中包含定义了一系列算法的方法。
创建具体的策略类,分别实现策略接口中的方法,每个具体策略类代表一个具体的算法。
在客户端中,持有一个策略接口的指针(或引用),可以动态切换不同的具体策略对象。
当客户端需要使用某个具体的算法时,调用策略接口中定义的方法即可。

  • 简单工厂模式:

创建一个工厂类,负责根据传入的参数来创建具体的对象。
工厂类中包含一个方法,根据不同的参数返回不同的具体对象实例。

  • 结合实现原理:

在策略模式中,客户端通常需要显式地创建具体策略对象,这可能会导致代码的复杂性。
为了解决这个问题,可以将具体策略对象的创建委托给简单工厂,通过简单工厂模式动态地创建具体的策略对象。
这样,客户端只需要和简单工厂打交道,向工厂传递参数即可获取所需的具体策略对象,而无需直接创建对象。
当需要在运行时根据不同条件选择不同的策略时,可以通过简单工厂来创建不同的策略对象,然后使用策略模式来执行具体的算法。

三、UML图

在这里插入图片描述
通过UML图可以发现简单工厂模式和策略模式+简单工厂模式非常的像啊!其主要差别就是工厂生成的类有一个统一执行的函数execute函数用来变成策略模式,进而就有了策略模式的特征了

四、示例代码

#include <iostream>
#include <memory>// 抽象策略类
class Strategy {
public:virtual void execute() const = 0;virtual ~Strategy() {}
};// 具体策略类 A
class ConcreteStrategyA : public Strategy {
public:void execute() const override {std::cout << "Executing strategy A\n";}
};// 具体策略类 B
class ConcreteStrategyB : public Strategy {
public:void execute() const override {std::cout << "Executing strategy B\n";}
};// 工厂类,用于创建具体策略对象
class StrategyFactory {
public:static Strategy* createStrategy(char type) {switch (type) {case 'A':return new ConcreteStrategyA;case 'B':return new ConcreteStrategyB;default:throw std::invalid_argument("Invalid strategy type");}}
};int main() {// 使用工厂类创建具体策略对象auto strategyA = StrategyFactory::createStrategy('A');auto strategyB = StrategyFactory::createStrategy('B');// 执行策略strategyA->execute();strategyB->execute();return 0;
}

在这里插入图片描述
抽象策略类(Strategy):定义了执行策略的接口 execute(),所有具体策略类都要实现这个接口。

具体策略类(ConcreteStrategyA 和 ConcreteStrategyB):实现了具体的策略,分别是策略 A 和策略 B。它们提供了不同的行为实现方式。

工厂类(StrategyFactory):用于创建具体策略对象。createStrategy 方法根据传入的参数类型决定创建哪种具体策略对象。

主函数(main):在 main 函数中,通过工厂类创建了具体的策略对象 strategyA 和 strategyB,分别对应策略 A 和策略 B。然后调用这些策略对象的 execute() 方法执行相应的策略。

实现决策的原理在于通过工厂类的 createStrategy 方法根据输入的参数类型来动态创建具体的策略对象。这种方式使得客户端代码与具体策略对象的创建过程解耦,同时利用了策略模式的灵活性,能够在运行时动态地切换不同的策略。


总结

策略模式与简单工厂模式的结合,能够很好地将对象的行为和对象的创建分离,使得系统更具灵活性和可扩展性。通过将具体策略对象的创建委托给简单工厂,我们可以在不改变客户端代码的情况下动态地切换不同的策略,从而更好地满足不同的业务需求。这种结合使用的设计模式在实际项目中具有广泛的应用价值,可以帮助我们更好地组织和管理代码结构,提高代码的可维护性和可扩展性。

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

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

相关文章

z1-5输入编码器实验

一. 实验内容 1、制作LED计数电路&#xff0c;输入是编号为1~5的5个开关&#xff0c;输出是5个发光二极管&#xff08;LED&#xff09; 点几号开关&#xff0c;就有几个LED发光。 2、制作一个5位输入3位输出的编码器&#xff0c; 输入的第5位为1&#xff0c;输出就是数字5对应…

鸿蒙Harmony应用开发—ArkTS声明式开发(容器组件:ColumnSplit)

将子组件纵向布局&#xff0c;并在每个子组件之间插入一根横向的分割线。 说明&#xff1a; 该组件从API Version 7开始支持。后续版本如有新增内容&#xff0c;则采用上角标单独标记该内容的起始版本。 子组件 可以包含子组件。 ColumnSplit通过分割线限制子组件的高度。初始…

SQLiteC/C++接口详细介绍之sqlite3类(三)

快速跳转文章列表&#xff1a;SQLite—系列文章目录 上一篇&#xff1a;SQLiteC/C接口详细介绍之sqlite3类&#xff08;二&#xff09; 下一篇&#xff1a;SQLiteC/C接口详细介绍之sqlite3类&#xff08;四&#xff09; 6.sqlite3_create_module与sqlite3_create_module_v2函数…

栈队列数组试题(三)——栈和队列的应用

一、单项选择题 01.栈的应用不包括( ). A.递归 B.表达式求值 C.括号匹配 D.缓冲区 02&#xff0e;表达式a* (bc)-d的后缀表达式是()。 A. abcd*一 B. abc*d- C. abc*d- …

简单了解 vim 编辑器最基础的操作

简单了解 vim 编辑器最基础的操作 vim 这个是 Linux 上自带的一个文本编辑器&#xff0c;使用 vim 就可以更灵活的对文件进行编辑了&#xff08;虽然和记事本的定位差不多,实际上vim的使用要复杂很多&#xff09; 1.打开文件 语法&#xff1a;vim 文件名 示例&#xff1a;…

速盾:cdn是什么和作用有哪些

CDN, 也叫内容分发网络&#xff08;Content Delivery Network&#xff09;&#xff0c;是一种构建在分布式网络基础上的网络技术&#xff0c;旨在提高页面的访问速度和用户体验。CDN通过在全球各地部署服务器节点&#xff0c;并将网站的静态和动态内容复制到这些节点上&#xf…

16.旋转图像

给定一个 n n 的二维矩阵 matrix 表示一个图像。请你将图像顺时针旋转 90 度。 你必须在 原地 旋转图像&#xff0c;这意味着你需要直接修改输入的二维矩阵。请不要 使用另一个矩阵来旋转图像。 示例 1&#xff1a; 输入&#xff1a;matrix [[1,2,3],[4,5,6],[7,8,9]] 输出&…

关于本地项目连接git远程仓库以及git设置ignore文件

一、本地项目如何连接git远程仓库 第一步&#xff0c; 首先我们在git上新建仓库。 第二步&#xff0c;打开本地项目文件夹&#xff0c;鼠标右键选择Git Bash Here 。 第三步&#xff0c;输入git init 命令&#xff08;在目录中创建新的 Git 仓库&#xff09;。 第四步&#xff…

Python强大的库和框架——NumPy

NumPy&#xff08;Numerical Python&#xff09;是一个用于科学计算的强大库&#xff0c;提供了支持大型、多维数组和矩阵的数据结构&#xff0c;以及用于处理这些数组的大量数学函数。 以下是关于 NumPy 的一些详解&#xff1a; 1. 安装 NumPy&#xff1a; 可以使用以下命令…

ubuntu 安装 infiniband 和 RoCE 驱动

下载驱动程序 驱动程序地址 https://network.nvidia.com/products/infiniband-drivers/linux/mlnx_ofed/ 安装 安装参考文档 https://docs.nvidia.com/networking/display/mlnxofedv24010331/installing+mlnx_ofed#src-2571322208_InstallingMLNX_OFED-InstallationProced…

BUGKU-WEB cookies

题目描述 题目截图如下&#xff1a; 进入场景看看&#xff1a; 解题思路 看源码看F12&#xff1a;看请求链接看提示&#xff1a;cookies欺骗 相关工具 插件&#xff1a;ModHeader或者hackbarbase64解密 解题步骤 看源码 就是rfrgrggggggoaihegfdiofi48ty598whrefeoia…

构建部署_Jenkins介绍与安装

构建部署_Jenkins介绍与安装 构建部署_Jenkins介绍与安装Jenkins介绍Jenkins安装 构建部署_Jenkins介绍与安装 Jenkins介绍 Jenkins是一个可扩展的持续集成引擎。 持续集成&#xff0c;就是通常所说的CI&#xff08;Continues Integration&#xff09;&#xff0c;可以说是现…

MySQL--深入理解MVCC机制原理

什么是MVCC&#xff1f; MVCC全称 Multi-Version Concurrency Control&#xff0c;即多版本并发控制&#xff0c;维持一个数据的多个版本&#xff0c;主要是为了提升数据库的并发访问性能&#xff0c;用更高性能的方式去处理数据库读写冲突问题&#xff0c;实现无锁并发。 什…

JUC之volatile关键字

Volatile 被volatile修饰的变量有两大特点&#xff1a;可见性与有序性 volatile的内存语义 volatile凭什么可以保证可见性和有序性&#xff1f;&#xff1f;&#xff1f;内存屏障 Memory Barrier 内存屏障 四大屏障 Volatile保证可见性、没有原子性&#xff0c;指令禁重…

手撕算法-对称二叉树

力扣101. 对称二叉树 链接 https://leetcode.cn/problems/symmetric-tree/description/ 题目描述 给你一个二叉树的根节点 root &#xff0c; 检查它是否轴对称。示例1&#xff1a;此树是对称的。示例2&#xff1a;此树也是对称的示例3&#xff1a;此树不对称 思路 一颗…

【WEEK3】学习目标及总结【SpringMVC】【中文版】

学习目标&#xff1a; 三周完成SpringMVC入门——第三周 感觉这周很难完成任务了&#xff0c;大概率还会有第四周 学习内容&#xff1a; 参考视频教程【狂神说Java】SpringMVC最新教程IDEA版通俗易懂数据处理JSON交互处理 学习时间及产出&#xff1a; 第三周 MON~FRI 2024.…

15 stack和queue的实现

栈和队列作为容器适配器,只需要将容器封装模板,传入什么容器用什么容器就好了 栈 #pragma oncetemplate <class T, class container vector<T>> class stack { public:void push(const T& x){_con.push_back(x);}void pop(){_con.pop_back();}T& top(){…

代码缺陷代价

目录 什么是语法缺陷什么是类型安全缺陷什么是内存和资源安全缺陷什么是并发安全缺陷什么是错误处理缺陷 什么是语法缺陷 语法缺陷是指程序中存在的语法错误或违反语法规则的问题。它通常是由于编程语言的语法规则不符合要求导致的。例如&#xff0c;缺少分号、括号不匹配、关…

peft模型微调--Prompt Tuning

模型微调&#xff08;Model Fine-Tuning&#xff09;是指在预训练模型的基础上&#xff0c;针对特定任务进行进一步的训练以优化模型性能的过程。预训练模型通常是在大规模数据集上通过无监督或自监督学习方法预先训练好的&#xff0c;具有捕捉语言或数据特征的强大能力。 PEF…

ubuntu(20.04)-安装JAVA环境-IDEA

1.下载IDEA 2.解压文件 sudo tar -zxvf idealC-2022.2.3.tar.gz -C /opt 3.添加环境变量&#xff1a; .vim ~/.bashrc export IDEA_HOME/opt/ideaIC-2022.2.3/ export PATH${IDEA_HOME}/bin:$PATH source ~/.bashrc 4.启动&#xff1a; cd /opt/ideaIC-2…