目录

  • 一、简单工厂模式(Simple Factory Pattern)
  • 二、工厂方法模式(Factory Method Pattern)
  • 三、抽象工厂模式(Abstract Factory Pattern)
  • 四、三者对比总结
  • 五、选择建议
    • 如果这篇文章对你有所帮助,渴望获得你的一个点赞!

抽象工厂模式、简单工厂模式和工厂方法模式都是创建型设计模式,它们的核心目的都是将对象的创建和使用分离,但在实现复杂度、灵活性和应用场景上存在显著差异。以下从定义、结构、适用场景和代码示例四个方面进行对比分析:

一、简单工厂模式(Simple Factory Pattern)

定义与结构

  • 定义:简单工厂模式是一种创建对象的方式,它将对象的创建逻辑封装在一个工厂类中,通过传入参数决定创建哪种产品。
  • 核心角色:
    • 工厂类(Factory):负责创建产品的静态方法。
    • 抽象产品(Product):定义产品的接口。
    • 具体产品(ConcreteProduct):实现抽象产品接口。

适用场景

  • 产品种类较少且创建逻辑简单。
  • 客户端只需通过参数指定需要创建的产品,不关心创建细节。

代码示例

// 抽象产品
class Shape {
public:virtual void draw() = 0;virtual ~Shape() = default;
};// 具体产品
class Circle : public Shape {
public:void draw() override { std::cout << "Circle::draw()" << std::endl; }
};class Rectangle : public Shape {
public:void draw() override { std::cout << "Rectangle::draw()" << std::endl; }
};// 简单工厂
class ShapeFactory {
public:static std::unique_ptr<Shape> createShape(const std::string& type) {if (type == "circle") return std::make_unique<Circle>();if (type == "rectangle") return std::make_unique<Rectangle>();return nullptr; // 错误处理}
};// 客户端使用
void client() {auto circle = ShapeFactory::createShape("circle");circle->draw(); // 输出: Circle::draw()
}

特点

  • 优点:实现简单,将对象创建集中管理。
  • 缺点:工厂类职责过重,新增产品需修改工厂类,违反开闭原则。

二、工厂方法模式(Factory Method Pattern)

定义与结构

  • 定义:工厂方法模式定义创建对象的接口,让子类决定实例化哪个类。工厂方法将产品的创建延迟到子类。
  • 核心角色:
    • 抽象工厂(AbstractFactory):声明工厂方法,返回抽象产品。
    • 具体工厂(ConcreteFactory):实现工厂方法,创建具体产品。
    • 抽象产品(Product):定义产品的接口。
    • 具体产品(ConcreteProduct):实现抽象产品接口。

适用场景

  • 当一个类不知道它所需要的对象的类时(如框架设计)。
  • 当一个类希望由其子类来指定创建对象时。
  • 当类将创建对象的职责委托给多个子类中的某一个,并且希望在运行时动态指定时。

代码示例

// 抽象产品
class Product {
public:virtual void operation() = 0;virtual ~Product() = default;
};// 具体产品
class ConcreteProductA : public Product {
public:void operation() override { std::cout << "ConcreteProductA::operation()" << std::endl; }
};class ConcreteProductB : public Product {
public:void operation() override { std::cout << "ConcreteProductB::operation()" << std::endl; }
};// 抽象工厂
class Factory {
public:virtual std::unique_ptr<Product> createProduct() = 0;virtual ~Factory() = default;
};// 具体工厂
class ConcreteFactoryA : public Factory {
public:std::unique_ptr<Product> createProduct() override {return std::make_unique<ConcreteProductA>();}
};class ConcreteFactoryB : public Factory {
public:std::unique_ptr<Product> createProduct() override {return std::make_unique<ConcreteProductB>();}
};// 客户端使用
void client(Factory& factory) {auto product = factory.createProduct();product->operation();
}// 使用示例
int main() {ConcreteFactoryA factoryA;client(factoryA); // 输出: ConcreteProductA::operation()ConcreteFactoryB factoryB;client(factoryB); // 输出: ConcreteProductB::operation()
}

特点

  • 优点:符合开闭原则,新增产品只需添加新的具体工厂,无需修改抽象工厂和客户端。
  • 缺点:工厂子类过多时会导致代码复杂度增加。

三、抽象工厂模式(Abstract Factory Pattern)

定义与结构

  • 定义:抽象工厂模式提供一个创建一系列相关或相互依赖对象的接口,而无需指定它们具体的类。
  • 核心角色:
    • 抽象工厂(AbstractFactory):声明创建多个抽象产品的方法。
    • 具体工厂(ConcreteFactory):实现抽象工厂的方法,创建一组具体产品。
    • 抽象产品族(AbstractProduct):定义多个产品的接口。
    • 具体产品(ConcreteProduct):实现抽象产品接口。

适用场景

  • 系统需要独立于产品的创建、组合和表示时。
  • 系统需要使用多个产品族中的一个,且产品之间有依赖关系。
  • 需要动态切换产品系列时(如跨平台 UI、主题系统)。

代码示例

// 抽象产品A
class AbstractProductA {
public:virtual void operationA() = 0;virtual ~AbstractProductA() = default;
};// 具体产品A1
class ProductA1 : public AbstractProductA {
public:void operationA() override { std::cout << "ProductA1::operationA()" << std::endl; }
};// 具体产品A2
class ProductA2 : public AbstractProductA {
public:void operationA() override { std::cout << "ProductA2::operationA()" << std::endl; }
};// 抽象产品B
class AbstractProductB {
public:virtual void operationB() = 0;virtual ~AbstractProductB() = default;
};// 具体产品B1
class ProductB1 : public AbstractProductB {
public:void operationB() override { std::cout << "ProductB1::operationB()" << std::endl; }
};// 具体产品B2
class ProductB2 : public AbstractProductB {
public:void operationB() override { std::cout << "ProductB2::operationB()" << std::endl; }
};// 抽象工厂
class AbstractFactory {
public:virtual std::unique_ptr<AbstractProductA> createProductA() = 0;virtual std::unique_ptr<AbstractProductB> createProductB() = 0;virtual ~AbstractFactory() = default;
};// 具体工厂1
class ConcreteFactory1 : public AbstractFactory {
public:std::unique_ptr<AbstractProductA> createProductA() override {return std::make_unique<ProductA1>();}std::unique_ptr<AbstractProductB> createProductB() override {return std::make_unique<ProductB1>();}
};// 具体工厂2
class ConcreteFactory2 : public AbstractFactory {
public:std::unique_ptr<AbstractProductA> createProductA() override {return std::make_unique<ProductA2>();}std::unique_ptr<AbstractProductB> createProductB() override {return std::make_unique<ProductB2>();}
};// 客户端使用
void client(AbstractFactory& factory) {auto productA = factory.createProductA();auto productB = factory.createProductB();productA->operationA();productB->operationB();
}// 使用示例
int main() {ConcreteFactory1 factory1;client(factory1); // 输出: ProductA1::operationA() 和 ProductB1::operationB()ConcreteFactory2 factory2;client(factory2); // 输出: ProductA2::operationA() 和 ProductB2::operationB()
}

特点

  • 优点:将产品族的创建封装,保证产品间的兼容性;易于切换产品系列。
  • 缺点:新增产品族需修改抽象工厂及其所有子类,违反开闭原则;实现复杂。

四、三者对比总结

维度简单工厂模式工厂方法模式抽象工厂模式
核心思想将对象创建逻辑封装在一个工厂类中定义创建对象的接口,由子类实现具体创建逻辑提供创建一系列相关产品的接口,无需指定具体类
工厂数量一个工厂类一个抽象工厂和多个具体工厂一个抽象工厂和多个具体工厂
产品数量一个产品等级结构一个产品等级结构多个产品等级结构(产品族)
扩展性新增产品需修改工厂类,违反开闭原则新增产品只需添加新的具体工厂,符合开闭原则新增产品族需修改抽象工厂,违反开闭原则
适用场景产品种类少且创建逻辑简单需要灵活扩展创建逻辑的场景创建相互依赖的产品族的场景
复杂度简单中等复杂

五、选择建议

  1. 优先使用简单工厂:当产品种类少且创建逻辑固定时。
  2. 使用工厂方法:当需要扩展性,且产品属于同一等级结构时。
  3. 使用抽象工厂:当需要创建多个相关产品,且产品间有依赖关系时。

在实际应用中,可根据需求灵活组合这些模式,例如在抽象工厂中使用工厂方法实现具体产品的创建,或使用简单工厂管理产品注册。


如果这篇文章对你有所帮助,渴望获得你的一个点赞!

在这里插入图片描述

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

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

相关文章

博图SCL中CONTINUE语句详解:高效循环控制案例

博图SCL中CONTINUE语句详解&#xff1a;高效循环控制利器 在博图&#xff08;TIA Portal&#xff09;的SCL&#xff08;结构化控制语言&#xff09;编程中&#xff0c;CONTINUE语句是优化循环流程的强大工具。它允许您**跳过当前循环迭代的剩余代码&#xff0c;直接进入下一次…

django HttpResponse 加返回码

在Django框架中&#xff0c;HttpResponse对象是用来构造HTTP响应并将其发送回客户端的。当你创建一个HttpResponse对象时&#xff0c;你可以指定一个返回码&#xff08;或状态码&#xff09;&#xff0c;这是HTTP响应的一部分&#xff0c;用来表示请求的处理结果。状态码是三位…

【俄语图片文字识别】批量识别俄语图片文字,识别俄语图片文字的操作步骤和注意事项

场景&#xff1a;在俄语学习&#xff0c;俄语工作中经常遇到一些文字图片&#xff0c;如何将韩语图片文字从图片上扣下来&#xff0c;我们可以直接复制粘贴&#xff0c;提高我们的工作效率 我们会用到一款小工具&#xff1a; 软件操作步骤&#xff1a; 第一步、打开软件 第二…

关于AB PLC的ethernet/IP 通信 c++搭建

1.下载开源的libplctag库 2.通过Cmake-gui生成工程文件 3.编译生成对应的Debug 4.配置VS studio 源码 #include "libplctag.h" #include <cstring> #include <iostream> #include <thread> int main() { plc_tag_set_debug_level(PLCTAG_DEB…

实验分享|自研局部DIC-GPU算法与开源GPU算法对比实验

1实验背景 数字图像相关法DIC是材料力学领域研究的关键技术&#xff0c;其中局部DIC凭借亚像素级精度、全场测量等优势&#xff0c;成为材料局部变形分析的优选方案。传统CPU计算难以应对局部DIC数万个子区并行计算需求&#xff0c;新兴GPU算法一定程度提高了计算效率&#xf…

P2066 机器分配

P2066 机器分配 - 洛谷 题目描述 总公司拥有高效设备M台&#xff0c;准备分给下属的N个分公司。各分公司若获得这些设备&#xff0c;可以为国家提供一定的盈利。问&#xff1a;如何分配这M台设备才能使国家得到的盈利最大&#xff1f;求出最大盈利值。其中M⩽15&#xff0c;N…

Vue 复制页面内容

方法 1&#xff1a;使用 document.execCommand(copy) 在用户触发的事件中 这种方法适用于用户触发的事件&#xff08;如点击按钮&#xff09;&#xff0c;因为这是 execCommand(copy) 的唯一允许场景。 <template><button click"copyToClipboard">复制…

暑期前端训练day1

js——记忆函数 2025-06-19 day1 一、记忆函数Ⅰ&#xff1a; 链接&#xff1a;https://leetcode.cn/problems/memoize/?envTypeproblem-list-v2&envIdGR5hbGen (1) 题意&#xff1a;给定一个函数&#xff0c;返回一个记忆版的函数&#xff0c;其中你只会包含三个可能输…

鸿蒙网络编程系列54-仓颉版实现Smtp邮件发送客户端

1. SMTP邮件发送客户端 在本系列的第4篇文章《鸿蒙网络编程系列4-实现SMTP邮件发送客户端》中&#xff0c;基于ArkTS语言在API9环境下使用TCPSocket对象演示了SMTP客户端的实现&#xff0c;并且通过腾讯邮件服务器执行了实际的邮件发送。不过&#xff0c;在2024年末&#xff0…

【慧游鲁博】【12】UI美化·图标选择与变换·动态交互·格式定义

文章目录 图标设计迭代过程初始版本问题分析优化措施 游览画卷美化原因当前效果展示美化步骤(1) 代码修改结构优化CSS&#xff08;优化样式&#xff09; (2) 图标选择&#xff08;4种方案&#xff09;(3) 交互优化 版本一版本二1. 修改HTML结构2. 新增CSS样式色彩控制技术性能优…

IMU介绍

IMU(Inertial Measurement Unit,惯性测量单元)是一种基于惯性原理的传感器,通过测量物体的加速度和角速度来获取运动状态信息。以下从技术原理、核心组件、应用场景及关键指标等方面展开详细解析: 一、IMU的技术原理与核心组件 1. 工作原理 惯性力学基础:利用牛顿第二定…

MOS管和比较器

目录 前言一、前置器件复习使用1.比较器工作特性2.光电二极管3.红外出水水龙头4.温控风扇工作原理 二、MOS管1.前置1.1 增强型MOS管1.2 耗尽型MOS管1.3 四种1.4 比较 2.基本结构3.导通条件4.开关电路的设计方法5.寄生电容问题6.寄生二极管不能忽略7.Nmos管做电源开关的注意事项…

从代码学习深度强化学习 - Double DQN PyTorch版

文章目录 前言理论篇:为什么需要 Double DQN?代码实现篇:构建一个 Double DQN 智能体2.1 项目设置与辅助函数2.2 环境 (Environment)2.3 DQN 的核心组件2.3.1 Replay Buffer (经验回放池)2.3.2 Q-Network (Q网络)2.3.3 The Double DQN Agent (Double DQN 智能体)训练与结果3…

四非鼠鼠计算机专业的保研分享

四非鼠鼠的计算机专业保研分享 1.前言 鼠鼠的本科学校是一所不怎么出名的四非院校&#xff0c;专业是计算机科学与技术。在写下这篇文章时&#xff0c;鼠鼠并不是为了炫耀什么&#xff0c;而是想把自己在保研路上的一些踩坑经历分享出来&#xff0c;尤其是写给那些和我一样&a…

【C++详解】STL-vector使用底层剖析和实现

文章目录 vector介绍vector和string的区别补充知识initializer_listemplace_back结构化绑定 vector的使用构造析构遍历修改insertfind流插入/流提取vector\<vector>(杨辉三角) vector模拟实现浅品STL源码构造函数拷贝构造多参数构造迭代器区间构造n个val初始化swapoperat…

MySql升级安装、socket 及密码重置

升级 项目需要使用Mysql8.0, 查看自己的ubuntu22.04上mysql版本为5.7&#xff0c; 使用以下命令自动升级到8.0版本。 sudo apt install Mysqlsock错误&#xff1a; Can’t connect to local MySQL server through socket 运行mysql -u -p 报以下错误&#xff1a; ERROR 200…

Python网络爬虫技术:从入门到实战

在当今数字化时代&#xff0c;网络爬虫技术已经成为数据挖掘和信息收集的重要工具。通过网络爬虫&#xff0c;我们可以高效地从互联网上获取大量有价值的数据&#xff0c;用于数据分析、市场研究、学术研究等多种场景。本文将带你从零开始&#xff0c;了解Python网络爬虫的基本…

偏微分方程初值问题求解

题目 问题 2. (a) u t + 3 u x − 2 u y = x ; u t + x u x + y u y = x ; u_t + 3u_x - 2u_y = x; \quad u_t + xu_x + yu_y = x; ut​+3ux​−2uy​=x;ut​+xux​+yuy​=x; u t + x u x − y u y = x ; u t + y u x + x u y = x ; u_t + xu_x - yu_y = x; \quad u_t + yu_…

【专业梳理】PMP知识体系,以SIPOC流程图为核心的质量工具扩展

​​1. SIPOC流程图:质量管理的起点​​ SIPOC(Supplier-Input-Process-Output-Customer)是六西格玛和流程管理中的核心工具,用于定义和优化跨职能流程。在PMBOK中,它与质量管理知识领域(尤其是质量规划、质量保证)紧密关联: ​​质量规划​​:通过SIPOC明确流程边界…

OpenCV指定pid和vid通过MSMF打开摄像头

在基于OpenCV的项目中&#xff0c;实际开发过程会面临设备上存在多个摄像头&#xff0c;需要指定摄像头的pid和vid打开摄像头。在OpenCV通过MSMF打开摄像头时&#xff0c;需要传入摄像头的index&#xff0c;因此需要在打开该摄像头前需要找出摄像头的index&#xff0c;下面给出…