工厂模式总结

工厂模式


1. 简单工厂模式(Simple Factory)

核心思想
  • 定义一个工厂类,根据输入参数创建不同的具体对象。
  • 客户端不直接调用具体类的构造函数,而是通过工厂类获取对象。
示例代码
#include <iostream>
#include <memory>// 抽象产品类
class Shape {
public:virtual void draw() = 0;virtual ~Shape() = default;
};// 具体产品类:圆形
class Circle : public Shape {
public:void draw() override {std::cout << "Drawing a Circle" << std::endl;}
};// 具体产品类:矩形
class Rectangle : public Shape {
public:void draw() override {std::cout << "Drawing a Rectangle" << std::endl;}
};// 简单工厂类
class ShapeFactory {
public:enum class Type { Circle, Rectangle };// 创建对象的方法static std::unique_ptr<Shape> createShape(Type type) {switch (type) {case Type::Circle:return std::make_unique<Circle>();case Type::Rectangle:return std::make_unique<Rectangle>();default:throw std::invalid_argument("Invalid shape type");}}
};// 客户端使用
int main() {auto circle = ShapeFactory::createShape(ShapeFactory::Type::Circle);circle->draw();  // Output: Drawing a Circleauto rect = ShapeFactory::createShape(ShapeFactory::Type::Rectangle);rect->draw();    // Output: Drawing a Rectanglereturn 0;
}
特点
  • 优点:代码简单,集中管理对象的创建逻辑。
  • 缺点:违反开闭原则(新增类型需修改工厂类)。

2. 工厂方法模式(Factory Method)

核心思想
  • 定义一个创建对象的抽象接口,由子类决定具体实例化的类。
  • 每个具体产品对应一个具体工厂类。
示例代码
#include <iostream>
#include <memory>// 抽象产品类
class Button {
public:virtual void render() = 0;virtual ~Button() = default;
};// 具体产品类:Windows 按钮
class WindowsButton : public Button {
public:void render() override {std::cout << "Rendering a Windows-style button" << std::endl;}
};// 具体产品类:MacOS 按钮
class MacOSButton : public Button {
public:void render() override {std::cout << "Rendering a MacOS-style button" << std::endl;}
};// 抽象工厂类
class ButtonFactory {
public:virtual std::unique_ptr<Button> createButton() = 0;virtual ~ButtonFactory() = default;
};// 具体工厂类:Windows 按钮工厂
class WindowsButtonFactory : public ButtonFactory {
public:std::unique_ptr<Button> createButton() override {return std::make_unique<WindowsButton>();}
};// 具体工厂类:MacOS 按钮工厂
class MacOSButtonFactory : public ButtonFactory {
public:std::unique_ptr<Button> createButton() override {return std::make_unique<MacOSButton>();}
};// 客户端使用
void renderUI(ButtonFactory& factory) {auto button = factory.createButton();button->render();
}int main() {WindowsButtonFactory winFactory;renderUI(winFactory);  // Output: Rendering a Windows-style buttonMacOSButtonFactory macFactory;renderUI(macFactory);  // Output: Rendering a MacOS-style buttonreturn 0;
}
特点
  • 优点:符合开闭原则,扩展新类型只需添加新工厂类。
  • 缺点:类数量增加,系统复杂度提升。

3. 抽象工厂模式(Abstract Factory)

核心思想
  • 提供一个接口,用于创建一组相关或依赖的对象家族
  • 适合需要创建多个协同工作的对象的场景(如 GUI 组件库)。
示例代码
#include <iostream>
#include <memory>// 抽象产品类:按钮
class Button {
public:virtual void render() = 0;virtual ~Button() = default;
};// 抽象产品类:文本框
class TextBox {
public:virtual void input() = 0;virtual ~TextBox() = default;
};// Windows 系列产品
class WindowsButton : public Button {
public:void render() override {std::cout << "Windows Button" << std::endl;}
};class WindowsTextBox : public TextBox {
public:void input() override {std::cout << "Windows TextBox" << std::endl;}
};// MacOS 系列产品
class MacOSButton : public Button {
public:void render() override {std::cout << "MacOS Button" << std::endl;}
};class MacOSTextBox : public TextBox {
public:void input() override {std::cout << "MacOS TextBox" << std::endl;}
};// 抽象工厂接口
class GUIFactory {
public:virtual std::unique_ptr<Button> createButton() = 0;virtual std::unique_ptr<TextBox> createTextBox() = 0;virtual ~GUIFactory() = default;
};// 具体工厂:Windows 工厂
class WindowsFactory : public GUIFactory {
public:std::unique_ptr<Button> createButton() override {return std::make_unique<WindowsButton>();}std::unique_ptr<TextBox> createTextBox() override {return std::make_unique<WindowsTextBox>();}
};// 具体工厂:MacOS 工厂
class MacOSFactory : public GUIFactory {
public:std::unique_ptr<Button> createButton() override {return std::make_unique<MacOSButton>();}std::unique_ptr<TextBox> createTextBox() override {return std::make_unique<MacOSTextBox>();}
};// 客户端使用
void createUI(GUIFactory& factory) {auto button = factory.createButton();auto textBox = factory.createTextBox();button->render();textBox->input();
}int main() {WindowsFactory winFactory;createUI(winFactory);  // Output: // Windows Button// Windows TextBoxMacOSFactory macFactory;createUI(macFactory);  // Output:// MacOS Button// MacOS TextBoxreturn 0;
}
特点
  • 优点:保证产品家族的兼容性(如统一风格)。
  • 缺点:扩展新产品家族需要修改所有工厂接口。

工厂模式的核心对比

模式适用场景扩展性复杂度
简单工厂对象类型少且固定违反开闭原则
工厂方法单一产品,需灵活扩展具体类型新增产品类型只需添加新工厂
抽象工厂需要创建一组相关的对象(产品家族)新增产品家族需修改接口

工厂模式的典型应用场景

  1. 跨平台 UI 开发:为不同操作系统创建风格一致的组件。
  2. 游戏开发:动态生成不同类别的敌人或道具。
  3. 数据库访问:根据配置创建 MySQL/Oracle 连接对象。
  4. 插件系统:加载第三方模块时动态创建对象。

最佳实践

  1. 优先使用工厂方法模式
    在需要灵活扩展时,避免简单工厂的硬编码逻辑。

  2. 结合智能指针管理对象
    使用 std::unique_ptrstd::shared_ptr 自动释放资源。

    std::unique_ptr<Button> button = factory.createButton();
    
  3. 避免过度设计
    如果对象创建逻辑简单,直接使用构造函数可能更高效。


总结

工厂模式通过封装对象的创建过程,实现以下目标:

  • 解耦:客户端代码与具体类解耦。
  • 可维护性:集中管理创建逻辑,便于修改和扩展。
  • 灵活性:支持动态切换产品类型或家族。

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

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

相关文章

MySQL的三种安装方式(mis、zip、yum)

目录 2.0数据库安装 2.1windows上.mis格式 环境准备 MySQL的安装 环境配置&#xff08;非必要&#xff09; 2.2windows上.zip格式安装 环境准备 配置文件的内容 MySQL的安装 附录可能出现问题 图形工具远程连接数据库 2.3Linux上安装yum包 环境准备 过程命令 My…

串口学习和蓝牙通信HC05(第八天)

&#x1f468;‍&#x1f4bb;个人主页&#xff1a;开发者-削好皮的Pineapple! &#x1f468;‍&#x1f4bb; hello 欢迎 点赞&#x1f44d; 收藏⭐ 留言&#x1f4dd; 加关注✅! &#x1f468;‍&#x1f4bb; 本文由 削好皮的Pineapple! 原创 &#x1f468;‍&#x1f4b…

设计总监的“轻量化”新武器:用Adobe Express,音频一键驱动动画

在快节奏的创意项目中&#xff0c;如何将复杂的设计理念或冗长的研究报告&#xff0c;快速转化为易于理解、富有吸引力的动态内容&#xff0c;是衡量一个团队沟通效率的关键。作为一名在海外设计界工作了十余年的设计师&#xff0c;我发现&#xff0c;最高效的团队&#xff0c;…

零知开源——STM32F407VET6驱动SHT41温湿度传感器完整教程

✔零知开源是一个真正属于国人自己的开源软硬件平台&#xff0c;在开发效率上超越了Arduino平台并且更加容易上手&#xff0c;大大降低了开发难度。零知开源在软件方面提供了完整的学习教程和丰富示例代码&#xff0c;让不懂程序的工程师也能非常轻而易举的搭建电路来创作产品&…

Linux流量分析:tcpdump wireshark

前言 最近因为工作需要&#xff0c;研究了下如何使用tcpdump和wireshark分析业务流量。如果要使用tcpdump分析具体的HTTP请求耗时&#xff0c;需捕获网络数据包并分析时间戳信息&#xff0c;重点关注TCP连接的建立、HTTP请求发送到响应接收的全过程。 以下是具体步骤和技巧&…

深度学习图像分类数据集—角膜溃疡识别分类

该数据集为图像分类数据集&#xff0c;适用于ResNet、VGG等卷积神经网络&#xff0c;SENet、CBAM等注意力机制相关算法&#xff0c;Vision Transformer等Transformer相关算法。 数据集信息介绍&#xff1a;角膜溃疡识别分类&#xff1a;[dot, mix, slice] 训练数据集总共有270张…

功能强、超好用【PDF转换工具】的介绍下载与安装教程

Windows 电脑上一款简单好用的PDF转换工具&#xff0c;可以轻松地将其他文档转换为 PDF 格式&#xff0c;也可以将 PDF 文件转换为其他格式&#xff0c;如常见的 Word、Excel、PPT 等。 此外软件还支持 Office 文档合并分割、旋转页面、拼接页面、删除文字、删除页面、添加水印…

c# 钉钉应用实现监听审批事件以及获取审批结果的流程

oa的操作已经测试了一遍 image.png如果是自建oa则代表发起的审批是跳转网页&#xff0c;否则钉钉打开后是一个表单界面&#xff0c;不需要调整自己搞得oa。 所以我感觉目前公司的需求更适合官方oa 表单来填写,更灵活&#xff0c;还支持用户配置。 但是用户点了审批&#xff0c;…

Typecho架构深度剖析:轻量级博客系统的设计哲学与实现原理

文章目录 深度解析Typecho:轻量级博客系统的架构设计与实现1. Typecho概述与技术背景1.1 发展历程1.2 核心特性2. 系统架构设计分析2.1 核心架构图2.2 核心组件3. 核心模块实现分析3.1 路由系统实现3.2 数据库抽象层4. 插件系统深度解析4.1 Hook机制实现4.2 插件开发示例5. 性…

LangChain 内存(Memory)

1. 为什么需要内存&#xff1f; 大型语言模型&#xff08;LLM&#xff09;本身是无状态的。这意味着每次你向 LLM 发送一个请求&#xff08;Prompt&#xff09;&#xff0c;它都会独立处理这个请求&#xff0c;完全不记得之前任何的交互。这在构建一次性问答应用时没问题&#…

基于定制开发开源AI智能名片S2B2C商城小程序的社群游戏定制策略研究

摘要&#xff1a;本文聚焦社群游戏定制领域&#xff0c;深入探讨以社群文化和用户偏好为导向的定制策略。通过分析互动游戏活动、社群文化塑造等关键要素&#xff0c;结合定制开发开源AI智能名片S2B2C商城小程序的技术特性&#xff0c;提出针对性游戏定制方案。研究旨在提升社群…

自动驾驶决策与规划

目录 自动驾驶决策与规划概述 决策与规划体系结构 分层递阶式决策规划 反应式体系结构 混合式体系结构 决策与规划系统的关键环节 路径规划 轨迹规划 行为决策 异常处理 自动驾驶的路径规划技术 维诺图法 栅格法 Dijkstra算法 A*算法 自动驾驶的行为决策方法 …

C++编译期计算:常量表达式(constexpr)全解析

在C性能优化领域&#xff0c;"将计算尽可能转移到编译期"是一条黄金法则。编译期计算&#xff08;Compile-Time Computation&#xff09;能显著减少程序运行时的开销&#xff0c;提升执行效率&#xff0c;同时还能在编译阶段暴露潜在错误。C11引入的constexpr关键字及…

【micro:bit】从入门到放弃(一):在线、离线版本的使用

1、离线版 micro:bit 1)下载地址 https://makecode.microbit.org/offline-app 2)双击安装包,makecode-microbit-setup-win64.exe,自动安装,安装成功后图标如下图所示 3)运行程序,查看版本信息 4)主界面如下 5)编程界面 点击“新建项目”或者“导入”进入编程界…

Flink Forward Asia 2025 主旨演讲精彩回顾

作为 Apache Flink 社区备受瞩目的年度盛会之一&#xff0c;由阿里云承办的 Flink Forward Asia 2025 于 7 月 3 日在新加坡正式拉开帷幕。From Real-Time Data Analytics to Real-Time AI&#xff0c;Flink 生态全面拥抱 AI本次大会上&#xff0c;Apache Flink 中文社区发起人…

车道偏离预警(LDW)功能介绍

车道偏离预警&#xff08;LDW&#xff09;功能介绍 LDW功能 通过摄像头监测前方车道线&#xff0c;当车辆偏离车道线时&#xff0c;系统发出报警提醒。 系统框图报警条件 最早报警线最迟报警线报警临界线 设置在 最早/最迟报警线 之间接口定义 输入/输出系统算法 横向偏离速度模…

软考(软件设计师)计算机网络-网络层

obsidian做markdown笔记太爽了&#xff0c;康奈尔模板笔记看起来舒服&#xff0c;CSDN试了几种方式&#xff0c;不支持&#xff0c;只能贴图了&#xff0c;将就看吧&#x1f60f;&#xff08;狗头保命&#xff09;工作原理图解 #mermaid-svg-e5Tgpt26jUftujKn {font-family:&qu…

nginx反向代理实现跨域请求

记录一个项目中遇到的跨域请求问题&#xff0c;解决跨域问题无非几种办法&#xff1a;1、后端解决&#xff0c;推荐的做法&#xff0c;可以看我之前写的文章&#xff0c;fastadmin的后台配置跨域&#xff1b;2、前端配置proxy代理&#xff08;开发环境用&#xff09;&#xff1…

利用Wisdom SSH高效搭建CI/CD工作流

在软件开发流程中&#xff0c;CI/CD工作流对于提升效率与确保质量起着关键作用。Wisdom SSH作为一款强大工具&#xff0c;其官网为ssh.wisdomheart.cn&#xff0c;借助AI助手能大幅简化CI/CD工作流的搭建过程。假设服务器已完成基础配置&#xff0c;下面为您介绍如何利用Wisdom…

深度学习-循环神经网络RNN

文章目录序列模型循环神经网络案例词的表示输出的表示矩阵运算表示交叉熵损失时间反向传播算法BPTT梯度消失与梯度爆炸GRULSTM总结序列模型 循环神经网络 st是上一个隐层的输出&#xff0c;体现序列数据之间有很强的关联性。 案例 > S0是初始输入&#xff0c;一般是0&#…