【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函数…

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

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

16.旋转图像

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

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;此树不对称 思路 一颗…

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…

什么是SFP光模块?如何选择?

SFP光模块作为全球制造商和供应商的行业标准&#xff0c;至今仍被广泛使用。在许多网络中&#xff0c;如SONET、千兆以太网、光纤通道、PON和其他通信标准中&#xff0c;SFP光模块已经成为行业的中坚力量。本指南将为您介绍一些关于选择SFP模块的技巧。 什么是SFP光模块&#…

Docker部署ChatGLM3、One API、FastGPT

创建并运行chatglm3容器 docker run --name chatglm3 -p 8000:8000 registry.cn-hangzhou.aliyuncs.com/ryyan/chatglm.cpp:chatglm3-q5_1 创建并运行one-api容器 (其中挂载路径 D:\one-api 可以选择你自己喜欢的目录) docker run --name oneapi -d -p 3000:3000 -e TZAsia…

Linux下的多线程编程:原理、工具及应用(2)

&#x1f3ac;慕斯主页&#xff1a;修仙—别有洞天 ♈️今日夜电波&#xff1a;Flower of Life—陽花 0:34━━━━━━️&#x1f49f;──────── 4:46 &#x1f504; ◀️ ⏸ ▶️ ☰ …

第二十四节 Java 异常处理

什么是异常&#xff1f; 程序运行时&#xff0c;发生的不被期望的事件&#xff0c;它阻止了程序按照程序员的预期正常执行&#xff0c;这就是异常。异常发生时&#xff0c;是任程序自生自灭&#xff0c;立刻退出终止&#xff0c;还是输出错误给用户&#xff1f;或者用C语言风格…

Machine Vision Technology:Lecture3 Edge detection | Fitting

Machine Vision Technology&#xff1a;Lecture3 Edge detection | Fitting Finite difference filters有限差分滤波器Effects of noise噪声对边缘检测影响Derivative theorem of convolution卷积的导数定理Derivative of Gaussian filter高斯滤波器的导数Smoothing vs. deriva…

后端系统开发之——创建SpringBoot工程

原文地址&#xff1a;后端框架系统开发之——创建SpringBoot工程 - Pleasure的博客 下面是正文内容&#xff1a; 前言 现在的市场环境&#xff0c;如果你单单只是作为前端工程师或者是后端工程师&#xff0c;在开发Web应用的时候都需要去读取企业提供的接口文档。而当你前后端…

【ARM】UBL本地服务器离线激活license

【更多软件使用问题请点击亿道电子官方网站查询】 1、 文档目标 UBL本地服务器离线激活license。 2、 问题场景 解决有用户外出时激活 license。 3、软硬件环境 1&#xff09;、软件版本&#xff1a;MDK5.39 2&#xff09;、电脑环境&#xff1a;Ubuntu 20.04 LTS 3&…

NCV4275CDT50RKG稳压器芯片中文资料规格书PDF数据手册引脚图图片价格功能

产品概述&#xff1a; NCV4275C 是一款低漏稳压器&#xff0c;可用于严酷汽车环境。它包括了较宽的运行温度范围和输出电压范围。输出调节为 5.0 V 或 3.3 V&#xff0c;额定输出电流为 450 mA。它还提供过电流保护、超温保护和可编程微处理器重置等多种功能。NCV4275C 采用 D…