当前位置: 首页 > article >正文

工厂方法模式的C++实现示例

核心思想

工厂方法模式是一种创建型设计模式,它定义了一个用于创建对象的接口,但让子类决定实例化哪一个类。工厂方法模式将对象的实例化过程推迟到子类,从而使得子类可以根据需要决定创建哪种对象。

**Product:**定义产品的接口。
**ConcreteProduct:**实现Product接口,是具体的产品。
**Factory:**定义工厂方法,返回一个Product对象。
**ConcreteFactory:**实现工厂方法,返回具体的ConcreteProduct。

工厂方法模式的核心是将对象的创建与使用分离,使得系统更加灵活和可扩展。

使用场景

框架设计:如框架需要定义通用的创建逻辑,但将具体实现留给子类。
可扩展性需求:当系统需要支持多种产品类型,且未来可能新增产品时。
解耦创建逻辑:当对象的创建逻辑复杂,或需要依赖外部资源时。
测试与模拟:在测试中,可以使用工厂方法创建模拟对象。
插件化架构:如插件系统需要动态加载和创建对象。

解决的问题

紧耦合问题:
在传统设计中,客户端直接通过new关键字创建对象,导致客户端与具体类紧耦合。工厂方法模式通过引入工厂接口,解耦了客户端和具体类。

代码重复问题:
如果多个地方需要创建相同的对象,创建逻辑可能分散在各处,导致代码重复。工厂方法模式将创建逻辑集中管理。

扩展性问题:
新增产品类型时,需要修改客户端代码。工厂方法模式允许通过新增子类来扩展系统,而无需修改现有代码。

复杂创建逻辑:
如果对象的创建逻辑复杂(如依赖注入、配置加载等),直接嵌入在客户端代码中会导致代码难以维护。工厂方法模式将复杂逻辑封装在工厂类中。

优点

开闭原则:新增产品类型只需添加新的工厂子类,无需修改现有代码。
解耦:客户端只需依赖工厂接口,而不需要知道具体产品的实现。
复用性:创建逻辑可以在多个上下文中复用。
可测试性:可以通过工厂方法创建模拟对象,便于测试。

缺点

类数量增加:每个产品都需要一个对应的工厂子类,可能导致类的数量增多。
复杂性增加:对于简单对象的创建,使用工厂方法模式可能显得过于复杂。
客户端需要了解工厂:客户端需要知道有哪些工厂,并选择合适的工厂。

示例代码

下面是一个基于C++11的工厂方法模式的示例,展示了如何通过工厂类来创建不同类型的对象。

#include <iostream>
#include <memory>// 抽象产品类
class Product {
public:virtual void use() = 0;virtual ~Product() = default;
};// 具体产品类A
class ConcreteProductA : public Product {
public:void use() override {std::cout << "Using ConcreteProductA" << std::endl;}
};// 具体产品类B
class ConcreteProductB : public Product {
public:void use() override {std::cout << "Using ConcreteProductB" << std::endl;}
};// 抽象工厂类
class Factory {
public:virtual std::unique_ptr<Product> createProduct() = 0;virtual ~Factory() = default;
};// 具体工厂类A
class ConcreteFactoryA : public Factory {
public:std::unique_ptr<Product> createProduct() override {return std::make_unique<ConcreteProductA>();}
};// 具体工厂类B
class ConcreteFactoryB : public Factory {
public:std::unique_ptr<Product> createProduct() override {return std::make_unique<ConcreteProductB>();}
};// 客户端代码
int main() {std::unique_ptr<Factory> factoryA = std::make_unique<ConcreteFactoryA>();std::unique_ptr<Product> productA = factoryA->createProduct();productA->use();std::unique_ptr<Factory> factoryB = std::make_unique<ConcreteFactoryB>();std::unique_ptr<Product> productB = factoryB->createProduct();productB->use();return 0;
}

代码解析

​抽象产品类 Product:定义了产品的接口,所有具体产品类都必须实现 use() 方法。
​具体产品类 ConcreteProductA 和 ConcreteProductB:分别实现了 Product 接口,定义了各自的行为。
​抽象工厂类 Factory:定义了工厂方法的接口,用于创建产品对象。
​具体工厂类 ConcreteFactoryA 和 ConcreteFactoryB:分别实现了 Factory 接口,负责创建具体的产品对象。
​客户端代码:通过工厂类创建产品对象,并调用其方法。

相关文章:

工厂方法模式的C++实现示例

核心思想 工厂方法模式是一种创建型设计模式&#xff0c;它定义了一个用于创建对象的接口&#xff0c;但让子类决定实例化哪一个类。工厂方法模式将对象的实例化过程推迟到子类&#xff0c;从而使得子类可以根据需要决定创建哪种对象。 **Product&#xff1a;**定义产品的接口…...

本地部署Qwen2.5-VL-7B-Instruct模型

本地部署Qwen2.5-VL-7B-Instruct模型 本地部署Permalink **创建环境** conda create -n qwenvl python3.11 -y# 报错&#xff1a; Solving environment: failedPackagesNotFoundError: The following packages are not available from current channels:# 处理&#xff1a; c…...

【C++学习篇】智能指针

目录 1. 智能指针的使用场景分析 2. RAII和智能指针的设计思路 3. C标准库智能指针的使用 4.shared_ptr和weak_ptr 4.1shared_ptr的循环引用问题 4.2 weak_ptr 1. 智能指针的使用场景分析 下⾯程序中我们可以看到&#xff0c;new了以后&#xff0c;我们也delete了&#xff0c…...

如何将JAR交由Systemctl管理?

AI越来越火了&#xff0c;我们想要不被淘汰就得主动拥抱。推荐一个人工智能学习网站&#xff0c;通俗易懂&#xff0c;风趣幽默&#xff0c;最重要的屌图甚多&#xff0c;忍不住分享一下给大家。点击跳转到网站 废话不多说&#xff0c;进入正题。下面开始说如何使用 systemctl…...

六足仿生机器人地形自适应步态规划研究

六足仿生机器人地形自适应步态规划研究 第1章 绪论第2章 机器人系统建模第3章 地形感知与建模第4章 自适应步态生成算法第5章 动力学仿真与实验第6章 驱动代码设计与实现源码&文档链接 第1章 绪论 1.1 研究背景与意义 1.2 国内外研究现状 1.2.1 多足机器人步态规划 1.2.2 …...

决策树(Decision Tree)基础知识

目录 一、回忆1、*机器学习的三要素&#xff1a;1&#xff09;*函数族2&#xff09;*目标函数2.1&#xff09;*模型的其他复杂度参数 3&#xff09;*优化算法 2、*前处理/后处理1&#xff09;前处理&#xff1a;特征工程2&#xff09;后处理&#xff1a;模型选择和模型评估 3、…...

【OpenCV C++】以时间命名存图,自动检查存储目录,若不存在自动创建, 按下空格、回车、Q、S自动存图

文章目录 // 保存图像的函数 void saveImage(const cv::Mat& frame) {// 生成唯一文件名auto now = std::chrono::system_clock::...

Excel基础(详细篇):总结易忽视的知识点,有用的细节操作

目录 写在前面基础篇Excel主要功能必会快捷键快捷键整理表LotusExcel的文件类型工作表基本操作表项操作选中与缩放边框线 自动添加边框线格式刷设置斜线表头双/多斜线表头不变形的:双/多斜线表头插入多行、多列单元格/行列的移动冻结窗口 方便查看数据打印的常见问题Excel格式…...

pytest中pytest.ini文件的使用

pytest.ini 是 pytest 测试框架的配置文件,它允许你自定义 pytest 的行为。通过在 pytest.ini 中设置各种选项,可以改变测试用例的发现规则、输出格式、插件行为等。以下详细介绍 pytest.ini 文件的使用。 1. 文件位置 pytest.ini 文件通常位于项目的根目录下,pytest 在运…...

Linux下学【MySQL】中如何实现:多表查询(配sql+实操图+案例巩固 通俗易懂版~)

每日激励&#xff1a;“不设限和自我肯定的心态&#xff1a;I can do all things。 — Stephen Curry” 绪论&#xff1a; 本章是MySQL篇中&#xff0c;非常实用性的篇章&#xff0c;相信在实际工作中对于表的查询&#xff0c;很多时候会涉及多表的查询&#xff0c;在多表查询的…...

非平稳时间序列分析(三)——季节模型(SARIMA、STL、Holt-Winters)

此前篇章&#xff08;平稳序列&#xff09;&#xff1a; 时间序列分析&#xff08;一&#xff09;——基础概念篇 时间序列分析&#xff08;二&#xff09;——平稳性检验 时间序列分析&#xff08;三&#xff09;——白噪声检验 时间序列分析&#xff08;四&#xff09;—…...

【web前端开发】CSS--CSS简介及其编写位置(上)

1、CSS简介 &#xff08;1&#xff09;CSS的全称为&#xff1a;层叠式样式表&#xff08;Cascading Style Sheets&#xff09; &#xff08;2&#xff09;CSS也是一种标记语言&#xff0c;用于给HTML结构设置样式&#xff0c;例如&#xff1a;文字大小、颜色、元素宽度等等…...

云原生时代的技术桥梁

在数字化转型的大潮中&#xff0c;企业面临着数据孤岛、应用间集成复杂、高成本与低效率等问题。这些问题不仅阻碍了企业内部信息的流通和资源的共享&#xff0c;也影响了企业对外部市场变化的响应速度。当前&#xff0c;这一转型过程从IT角度来看&#xff0c;已然迈入云原生时…...

【数据结构】什么是栈||栈的经典应用||分治递归||斐波那契问题和归并算法||递归实现||顺序栈和链栈的区分

文章目录 &#x1f967;栈的初步理解&#xff1a;&#x1f967;易错&#xff1a;如何判断栈满&#x1f967;栈满理解&#x1f967;栈的基本运算&#x1f4da;栈操作的伪代码逻辑&#xff08;顺序和链栈&#xff09;&#x1f4d5;顺序栈运算实现&#xff1a;顺序栈的表示&#x…...

雷池WAF的为什么选择基于Docker

Docker 是一种开源的容器化平台&#xff0c;可以帮助开发人员将应用程序及其所有依赖项打包到一个称为容器的独立、可移植的环境中。Docker 的核心概念包括以下几点&#xff1a; 容器&#xff1a;Docker 使用容器来封装应用程序及其依赖项&#xff0c;使其能够在任何环境中都能…...

Ubuntu20.04双系统安装及软件安装(七):Anaconda3

Ubuntu20.04双系统安装及软件安装&#xff08;七&#xff09;&#xff1a;Anaconda3 打开Anaconda官网&#xff0c;在右侧处填写邮箱&#xff08;要真实有效&#xff01;&#xff09;&#xff0c;然后Submit。会出现如图示的Success界面。 进入填写的邮箱&#xff0c;有一封Ana…...

文件上传漏洞:upload-labs靶场11-20

目录 pass-11 pass-12 pass-13 pass-14 pass-15 pass-16 pass-17 pass-18 pass-19 pass-20 pass-11 分析源代码 &#xff0c;发现上传文件的存放路径可控 if(isset($_POST[submit])){$ext_arr array(jpg,png,gif);$file_ext substr($_FILES[upload_file][name],st…...

HTTP协议(20250305)

1. 万维网 WWW(World Wide Web)世界范围内的&#xff0c;联机式的信息储藏所&#xff0c;万维网解决了获取互联网上的数据时需要解决的以下问题&#xff1a; 怎样标识分布在整个互联网上的文档 URL用什么样的协议实现万维网上的各种链接 HTTP怎么使用户能够方便的查看文档数…...

Qt中txt文件输出为PDF格式

main.cpp PdfReportGenerator pdfReportGenerator;// 加载中文字体if (QFontDatabase::addApplicationFont(":/new/prefix1/simsun.ttf") -1) {QMessageBox::warning(nullptr, "警告", "无法加载中文字体");}// 解析日志文件QVector<LogEntr…...

《大语言模型的原理发展与应用》:此文为AI自动生成

《大语言模型的原理发展与应用》&#xff1a;此文为AI自动生成 一、引言&#xff1a;大语言模型&#xff0c;AI 时代的 “新引擎” 在当今数字化浪潮中&#xff0c;大语言模型宛如一颗璀璨的明星&#xff0c;照亮了人工智能发展的道路&#xff0c;成为推动各领域变革的核心驱…...

FPGA 高速接口Aurora8B/10B 协议详解与仿真

FPGA 高速接口Aurora8B/10B 协议详解与IP仿真 1 摘要 Aurora 8B/10B 是一种用于高速串行通信的协议&#xff0c;通常用于 FPGA 设计和其他数字通信应用。即一种编码方案&#xff0c;旨在在传输数据时提供可靠性、时钟恢复和错误检测。主要用于在点对点串行链路间移动数据的可…...

大白话Vue 源码

大白话Vue 源码 整体介绍 Vue 源码就像是一个超厉害的“魔法工具箱”&#xff0c;它能帮咱们轻松地做出各种漂亮又好用的网页。这个工具箱里有好几个关键的“魔法道具”&#xff0c;分别是响应式系统、虚拟 DOM、模板编译、组件系统和生命周期钩子&#xff0c;下面咱一个一个…...

grpc工具使用

工具安装 protoc 访问protoc release&#xff0c;根据系统型号&#xff0c;下载对应版本的protoc工具&#xff0c;并将下载到的可执行文件存放于$path中 安装完成后&#xff0c;可通过protoc --version指令校验是否安装成功 protoc --version # 输出&#xff1a; # libprotoc…...

ESP8266连接网络实时上传数据

要实现这个功能,可以按照以下步骤进行编程。我们将使用Arduino IDE来编写代码,并结合ESP8266的WiFi库、MQTT库以及Web服务器库来实现。 1. 准备工作 硬件:ESP8266开发板、温度传感器(如DS18B20)、显示屏(如OLED)。软件:Arduino IDE、ESP8266库、PubSubClient库(MQTT)…...

【手撕算法】支持向量机(SVM)从入门到实战:数学推导与核技巧揭秘

摘要 支持向量机&#xff08;SVM&#xff09;是机器学习中的经典算法&#xff01;本文将深入解析最大间隔分类原理&#xff0c;手撕对偶问题推导过程&#xff0c;并实战实现非线性分类与图像识别。文中附《统计学习公式手册》及SVM调参指南&#xff0c;助力你掌握这一核心算法…...

定制化开发的WooCommerce独立站商城更安全

定制化开发的WooCommerce独立站商城在安全性、交易风险控制以及整体用户体验方面有显著优势。以下是定制化开发在这些方面的具体表现&#xff1a; 1. 安全性更高 定制化开发允许开发者从底层架构开始设计和优化&#xff0c;确保网站的安全性。以下是具体表现&#xff1a; (1…...

AORO P9000 PRO三防平板携手RTK高精度定位,电力巡检效率倍增

电网系统覆盖幅员辽阔&#xff0c;每年因设备故障导致的巡检耗时超过百万工日。传统巡检模式受限于定位误差、设备防护不足和作业效率低下三大核心痛点&#xff0c;亟需智能化工具的突破性革新。为了满足这一需求&#xff0c;遨游通讯推出AORO P9000 PRO三防平板&#xff0c;以…...

游戏引擎学习第135天

仓库:https://gitee.com/mrxiao_com/2d_game_3 回顾 game_asset.cpp 的创建 在开发过程中&#xff0c;不使用任何现成的游戏引擎或第三方库&#xff0c;而是直接基于 Windows 进行开发&#xff0c;因为 Windows 目前仍然是游戏的标准平台&#xff0c;因此首先在这个环境中进行…...

安全渗透测试的全面解析与实践

引言 随着网络安全威胁的日益增加&#xff0c;企业和组织对自身系统的安全性提出了更高的要求。安全渗透测试&#xff08;Penetration Testing&#xff0c;简称渗透测试&#xff09;作为主动发现和修复系统安全漏洞的重要手段&#xff0c;已成为安全防护体系中的关键环节。本文…...

关联封号率降70%!2025最新IP隔离方案实操手册

高效运营安全防护&#xff0c;跨境卖家必看的风险规避指南 跨境账号管理的核心挑战&#xff1a;关联封号风险激增 2024年&#xff0c;随着全球电商平台对账号合规的审查日益严苛&#xff0c;“关联封号”已成为跨境卖家最头疼的问题之一。无论是同一IP登录多账号、员工操作失误…...