C++设计模式之创建型模式:工厂方法模式(Factory Method) - 教程

news/2025/9/25 17:19:04/文章来源:https://www.cnblogs.com/yxysuanfa/p/19111605

工厂方法模式(Factory Method)是创建型设计模式的一种,它定义了一个创建对象的接口,但将具体对象的实例化延迟到子类中。这种模式通过封装对象创建过程,实现了“创建与利用分离”,提高了代码的灵活性和可扩展性。

核心角色

工厂方法模式囊括4个关键角色:

  1. 产品(Product):定义所有具体产品的公共接口。
  2. 具体产品(ConcreteProduct):搭建产品接口的具体类。
  3. 工厂(Creator):声明工厂途径(用于创建产品),返回产品类型。
  4. 具体工厂(ConcreteCreator):实现工厂方法,返回具体产品实例。

实现示例

假设我们需要设计一个文档编辑器,支持创建不同类型的文档(如文本文档、表格文档),使用工厂方法模式的实现如下:

#include <iostream>#include <string>// 1. 产品接口(Product)class Document{public:virtual void open() = 0;virtual void save() = 0;virtual ~Document() = default;// 虚析构函数};// 2. 具体产品A(ConcreteProduct)class TextDocument: public Document {public:void open() override {std::cout <<"打开文本文档" << std::endl;}void save() override {std::cout <<"保存文本文档" << std::endl;}};// 2. 具体产品B(ConcreteProduct)class SpreadsheetDocument: public Document {public:void open() override {std::cout <<"打开表格文档" << std::endl;}void save() override {std::cout <<"保存表格文档" << std::endl;}};// 3. 工厂接口(Creator)class Application{public:// 工厂方法(纯虚函数,由子类实现)virtual Document* createDocument() = 0;// 业务方法(使用产品)void newDocument() {Document* doc = createDocument();// 调用工厂方法创建产品doc->open();// 其他操作...delete doc;// 释放资源}virtual ~Application() = default;};// 4. 具体工厂A(ConcreteCreator)class TextEditor: public Application {public:// 实现工厂方法:创建文本文档Document* createDocument() override {return new TextDocument();}};// 4. 具体工厂B(ConcreteCreator)class SpreadsheetEditor: public Application {public:// 实现工厂方法:创建表格文档Document* createDocument() override {return new SpreadsheetDocument();}};// 客户端代码int main() {// 创建文本编辑器(具体工厂)Application* textApp = new TextEditor();textApp->newDocument();// 内部会创建文本文档// 创建表格编辑器(具体工厂)Application* sheetApp = new SpreadsheetEditor();sheetApp->newDocument();// 内部会创建表格文档// 释放资源delete textApp;delete sheetApp;return 0;}

代码解析

  1. 产品接口(Document):定义了所有文档的通用行为(open()save())。
  2. 具体产品TextDocumentSpreadsheetDocument 分别实现了文本文档和表格文档的具体功能。
  3. 工厂接口(Application):声明了工厂方法 createDocument(),并通过 newDocument() 方法使用产品(体现“创建与使用分离”)。
  4. 具体工厂TextEditorSpreadsheetEditor 分别实现了创建文本文档和表格文档的工厂方法。

核心优势

  1. 解耦:客户端无需知道具体产品的类名,只需通过工厂接口创建对象。
  2. 可扩展性:新增产品时,只需添加对应的具体产品类和具体工厂类,无需修改现有代码(符合开闭原则)。
  3. 灵活性:经过更换具体工厂,可动态改变程序所使用的产品类型。

适用场景

  1. 当一个类不知道它所需要创建的对象的具体类型时。
  2. 当一个类希望由子类来决定创建哪个对象时。
  3. 当需要集中管理对象的创建逻辑,且未来可能扩展更多产品类型时。

与简单工厂模式的区别

工厂方法模式更适合产品类型较多或需要频繁扩展的场景,是对轻松工厂模式的进一步抽象和优化。

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

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

相关文章

【铸网-2025】线下赛 web 详细题解

<?php show_source(index.php); class MGkk8 {public $a;public $b;public function rpl2(){echo(MGrp12;);$b = $this->b;if ($this->a == "RPG") {echo(ifyes;);($b->a)($b->b."&quo…

2025/9/25

A 用时:1h 预期:100pts 实际:100pts 发现有两种做法,可以直接模拟,递推,复杂度分别为 \(O(n^2)\),\(O(n^2\log n)\),而递推可以用 bitset 压一下。 考虑根号分治复杂度为 \(O(B \times n+\frac{n^2\times log …

唐山市政建设总公司网站重庆装修设计公司排名

181/2461/8938产品概述 R&S SMU200A信号发生器旨在满足现代通信系统研发及其生产中遇到的所有要求。R&S SMU200A矢量信号发生器不仅将多达两个独立的信号发生器组合在一个只有四个高度单位的机柜中&#xff0c;还提供无与伦比的RF和基带特性。 Rohde & Schwarz S…

为什么要建设档案网站个人网页设计思路流程内容

142873-41-4脂质过氧化抑制剂1 英文名称&#xff1a;Lipid peroxidation inhibitor 1 中文名称&#xff1a;脂质过氧化抑制剂 化学名称&#xff1a;2,4,6,7-四甲基-2-[(4-苯基哌啶-1-基)甲基]-3H-1-苯并呋喃-5-胺 CAS&#xff1a;142873-41-4 外观&#xff1a;固体粉末 分…

网站建设 云南如何布局网站

标题链接【RM2021 四川站第二期直播】步兵设计及弹道测试https://bbs.robomaster.com/forum.php?modviewthread&tid11504&extrapage%3D1%26filter%3Dtypeid%26orderby%3Ddateline【RM2021 黑龙江站第4期直播】步兵机械设计入门2https://bbs.robomaster.com/forum.php?…

读书笔记:揭开索引的两个常见误区

我们的文章会在微信公众号IT民工的龙马人生和博客网站( www.htz.pw )同步更新 ,欢迎关注收藏,也欢迎大家转载,但是请在文章开始地方标注文章出处,谢谢! 由于博客中有大量代码,通过页面浏览效果更佳。本文为个人学…

国标GB28181平台EasyGBS如何赋能路网数字化管理与应急指挥?

国标GB28181平台EasyGBS如何赋能路网数字化管理与应急指挥?随着智慧交通建设的深入,海量、异构的道路监控设备如何实现统一接入、低延迟调阅与智能分析成为关键挑战。本文探讨基于GB/T28181国家标准的EasyGBS视频平台…

完整教程:Spring Boot 核心注解分类与应用指南

完整教程:Spring Boot 核心注解分类与应用指南pre { white-space: pre !important; word-wrap: normal !important; overflow-x: auto !important; display: block !important; font-family: "Consolas", &…

分布式数据库迁移OceanBase——基于网易云音乐自研CDC服务的平滑迁移方案

分布式数据库迁移OceanBase——基于网易云音乐自研CDC服务的平滑迁移方案网易云音乐在大体量的业务数据背后,是何种技术方案在支撑?本文分享网易云音乐PB级分库分表架构向原生分布式数据库架构迁移的技术优化经验。编…

获取用户ip所在城市

整体流程图获取当前登录用户所在城市,是一个非常常见的需求,在很多业务场景中用到。 比如:导航的定位功能默认选择的城市,或者一些防盗系统中识别用户两次登录的城市不一样的会有报警提示。 下载geoip2数据库 geoi…

郑州市网站建设公司石河子规划建设局网站

文章目录 &#x1f4d6; 前言1. 认识URL && 引入http协议2. http协议格式2.1 宏观格式&#xff1a;2.2 实验演示&#xff1a; 3. http的方法3.1 GET方法&#xff1a;3.2 POST方法&#xff1a;3.3 GET vs POST&#xff1a; 4. HTTP的报头和状态码5. http的cookie5.1 htt…

电商外贸网站建设新网域名自助管理平台

ANSYS Fluent和COMSOL Multiphysics以及OpenFOAM这3款CFD软件哪个好&#xff1f;cfd软件中哪款最实用&#xff1f;cfd软件有哪些&#xff1f;今天就给大家带来这几款CFD软件对比分析&#xff0c;一起来看看吧。 ANSYS Fluent ANSYS Fluent 是一种流行的计算流体动力学 (CFD) …

【Proteus仿真】AT89C51单片机串行数据转换为并行仿真 - 实践

【Proteus仿真】AT89C51单片机串行数据转换为并行仿真 - 实践pre { white-space: pre !important; word-wrap: normal !important; overflow-x: auto !important; display: block !important; font-family: "Cons…

第13章 day14-15 Webpack逆向

Webpack逆向 Webpack是一个现代的静态模块打包工具,它主要用于前端开发中的模块化打包和构建。通过Webpack,开发者可以将多个模块(包括JavaScript、CSS、图片等)进行打包,生成优化后的静态资源文件,以供在浏览器…

Viper远程配置踩坑记录

尝试etcd做配置中心,就用了Viper。没想到踩了一堆坑,记录一下。 一开始的代码是这么写的,想着先监听再读取: func initViperRemote() {err := viper.AddRemoteProvider("etcd3","http://127.0.0.1:…

深入解析:JVM(六)-- StringTable

pre { white-space: pre !important; word-wrap: normal !important; overflow-x: auto !important; display: block !important; font-family: "Consolas", "Monaco", "Courier New", …

开发一个彩票网站多少钱济南医院网站建设服务公司

来源&#xff1a;AI科技评论作者&#xff1a;陈彩娴、Mr Bear编辑&#xff1a;青暮近日&#xff0c;图灵奖得主、“贝叶斯网络之父”Judea Pearl在Twitter上分享了一篇新论文“What are the most important statistical ideas of the past 50 years?”&#xff08;过去50年中最…

医院网站系统源码怎么推广引流

Linux平台 一、从yum源脚本安装部署Zabbix-Agent,添加Linux Servers/PC 概述 Zabbix 主要有以下几个组件组成: Zabbix Server:Zabbix 服务端,Zabbix的核心组件,它负责接收监控数据并触发告警,还负责将监控数据持久化到数据库中。 Zabbix Agent:Zabbix客户端,部署在被监…

国产智能体脂秤PCBA方案设计

一、产品介绍:智能体脂秤是一款高精度、多功能的健康管理工具,通过测量身体脂肪百分比、肌肉质量、骨骼密度等参数,帮助用户了解自身身体健康状况,并提供个性化的健康建议。其结构设计紧凑,外观简约时尚,适用于家…

完整教程:JRE、JDK、JVM 及 JIT 之间有什么不同?

完整教程:JRE、JDK、JVM 及 JIT 之间有什么不同?pre { white-space: pre !important; word-wrap: normal !important; overflow-x: auto !important; display: block !important; font-family: "Consolas"…