【设计模式】简单工厂模式
C语言实现简单的工厂模式
#include <stdio.h>
#include <stdlib.h>// 图形类型枚举
typedef enum {CIRCLE,SQUARE,RECTANGLE
} ShapeType;// 图形结构体
typedef struct {ShapeType type;float area;
} Shape;// 创建圆形
Shape* createCircle() {Shape* circle = (Shape*)malloc(sizeof(Shape));circle->type = CIRCLE;circle->area = 0.0;return circle;
}// 创建正方形
Shape* createSquare() {Shape* square = (Shape*)malloc(sizeof(Shape));square->type = SQUARE;square->area = 0.0;return square;
}// 创建长方形
Shape* createRectangle() {Shape* rectangle = (Shape*)malloc(sizeof(Shape));rectangle->type = RECTANGLE;rectangle->area = 0.0;return rectangle;
}// 工厂方法根据类型创建图形
Shape* createShape(ShapeType type) {switch (type) {case CIRCLE:return createCircle();case SQUARE:return createSquare();case RECTANGLE:return createRectangle();default:return NULL;}
}int main() {Shape* circle = createShape(CIRCLE);Shape* square = createShape(SQUARE);Shape* rectangle = createShape(RECTANGLE);// 假设这里对图形对象进行了一些操作// 释放内存free(circle);free(square);free(rectangle);return 0;
}
C++实现简单的工厂模式
#include <iostream>// 图形类型枚举
enum class ShapeType {CIRCLE,SQUARE,RECTANGLE
};// 图形基类
class Shape {
public:virtual ~Shape() {}virtual float getArea() = 0;
};// 圆形类
class Circle : public Shape {
public:Circle() {std::cout << "Creating Circle..." << std::endl;}float getArea() override {std::cout << "Calculating Circle Area..." << std::endl;// 计算圆形面积的具体实现return 0.0;}
};// 正方形类
class Square : public Shape {
public:Square() {std::cout << "Creating Square..." << std::endl;}float getArea() override {std::cout << "Calculating Square Area..." << std::endl;// 计算正方形面积的具体实现return 0.0;}
};// 长方形类
class Rectangle : public Shape {
public:Rectangle() {std::cout << "Creating Rectangle..." << std::endl;}float getArea() override {std::cout << "Calculating Rectangle Area..." << std::endl;// 计算长方形面积的具体实现return 0.0;}
};// 图形工厂类
class ShapeFactory {
public:static Shape* createShape(ShapeType type) {switch (type) {case ShapeType::CIRCLE:return new Circle();case ShapeType::SQUARE:return new Square();case ShapeType::RECTANGLE:return new Rectangle();default:std::cout << "Invalid Shape Type!" << std::endl;return nullptr;}}
};int main() {Shape* circle = ShapeFactory::createShape(ShapeType::CIRCLE);Shape* square = ShapeFactory::createShape(ShapeType::SQUARE);Shape* rectangle = ShapeFactory::createShape(ShapeType::RECTANGLE);// 假设这里对图形对象进行了一些操作// 删除对象,避免内存泄漏delete circle;delete square;delete rectangle;return 0;
}
工厂模式的优缺点:
优点:
封装对象的创建:工厂模式将对象的创建过程封装在工厂类中,客户端代码无需直接调用构造函数来创建对象,从而降低了代码耦合度。
易于扩展:如果需要添加新类型的产品(图形),只需要添加一个新的产品类和对应的工厂方法即可,不需要修改现有代码,符合开闭原则。
屏蔽具体实现:客户端只需与抽象产品和抽象工厂进行交互,不关心具体的产品类和工厂类,隐藏了产品对象的具体实现。
创建对象的集中管理:所有产品的创建都在工厂类中,便于统一管理和维护。
容易调试:通过在工厂方法中添加打印语句,可以方便地观察对象的创建过程和其他信息,便于调试。
缺点:
增加了类的个数:每个具体产品都需要一个对应的具体工厂类,如果产品较多,会增加类的数量,增加系统复杂性。
增加了系统抽象性:引入工厂类和抽象产品,增加了系统的抽象性和理解难度,增加开发难度。
不易理解:工厂模式的代码会比直接创建对象的方式复杂,理解起来可能会有一定困难。
可能造成额外开销:在运行时使用工厂方法创建对象可能会比直接使用构造函数创建对象稍微慢一些,因为需要进行动态内存分配。但在实际应用中,这个开销通常是可以忽略不计的。
综上所述,工厂模式是一种灵活且可扩展的设计模式,它通过封装对象的创建过程,帮助我们降低代码的耦合度,并支持系统的扩展和维护。工厂模式适用于需要在运行时动态创建对象的场景,例如创建不同类型的图形、产品、对象等。通过工厂模式,我们可以更加灵活地管理对象的创建,使代码结构更加清晰和易于维护。
然而,工厂模式也有一些局限性,例如增加了类的数量和抽象性,可能会增加代码的复杂性和理解难度。在使用工厂模式时,需要根据实际情况来选择合适的设计方案,避免过度设计。对于简单的应用场景,直接使用构造函数创建对象可能更为简单和直观。
总的来说,工厂模式是一种有用的设计模式,它在合适的场景下可以为我们提供更好的设计和代码组织结构。对于复杂的系统,特别是涉及到大量对象创建和管理的情况,工厂模式可以发挥更大的优势。在实际项目中,根据具体需求和复杂度选择是否使用工厂模式是很重要的。
相关文章:
【设计模式】简单工厂模式
C语言实现简单的工厂模式 #include <stdio.h> #include <stdlib.h>// 图形类型枚举 typedef enum {CIRCLE,SQUARE,RECTANGLE } ShapeType;// 图形结构体 typedef struct {ShapeType type;float area; } Shape;// 创建圆形 Shape* createCircle() {Shape* circle …...
推荐系统-ALS协同过滤算法实现
从协同过滤的分类来说,ALS(Alternating Least Squares,交替最小二乘)算法属于User-Item CF,也叫做混合CF,它同时考虑了User和Item两个方面,通过数量相对少的未被观察到的隐藏因子,来…...
QT第三讲
思维导图 蜡笔小新闹钟 需求: 实现 widget.h #ifndef WIDGET_H #define WIDGET_H#include <QWidget> #include<QTime> //时间类 #include<QTimerEvent> //事件处理类 #include<QtTextToSpeech> //文本转语音类 #include<QMessageBo…...
Linux内核的I2C驱动框架详解------这应该是我目前600多篇博客中耗时最长的一篇博客
目录 1 I2C驱动整体框架图 2 I2C控制器 2.1 I2C控制器设备--I2C控制器在内核中也被看做一个设备 2.2 i2c控制器驱动程序 2.3 platform_driver结构体中的probe函数做了什么 2.3.1 疑问: i2cdev_notifier_call函数哪里来的 2.3.2 疑问:为什么有两…...
【点云处理教程】05-Python 中的点云分割
一、说明 这是我的“点云处理”教程的第 5 篇文章。“点云处理”教程对初学者友好,我们将在其中简单地介绍从数据准备到数据分割和分类的点云处理管道。 在上一教程中,我们看到了如何过滤点云以减少噪声或其密度。在本教程中,我们将应用一些聚…...
代码随想录算法训练营之JAVA|第十七天| 654. 最大二叉树
今天是第17天刷leetcode,立个flag,打卡60天。 算法挑战链接 654. 最大二叉树https://leetcode.cn/problems/maximum-binary-tree/description/ 第一想法 错误的想法,就不说了。 看完代码随想录之后的想法 用递归模拟真实的过程 如果我…...
C++重写函数、隐藏函数、重载函数的区别对比
目录 1.函数重载 1.1定义 1.2函数重载的规则: 1.3函数重载的作用: 2.函数重写: 2.1定义 2.2例子: 3.函数隐藏 3.1定义 3.2举个例子: 1.函数重载 1.1定义 我们在学类和对象的封装特性时学过一个词叫重载,…...
15.python设计模式【函数工厂模式】
1.知识讲解 内容:定义一个字典,在python中一切皆对象,将所有的函数进行封装,然后定一个分发函数进行分发,将原来if…else全部干掉。角色: 函数(function)函数工厂(funct…...
Redis主从复制、哨兵、cluster集群原理+实验
目录 一、Redis 主从复制 1、主从复制的作用 2、主从复制流程 3、搭建Redis 主从复制 安装Redis(所有主机) 修改Master节点Redis配置文件 修改Slave节点Redis配置文件 验证主从效果 一、Redis 主从复制 主从复制,是指将一台Redis服务器的数据&am…...
微信小程序如何实现页面传参?
前言 只要你的小程序超过一个页面那么可能会需要涉及到页面参数的传递,下面我总结了 4 种页面方法。 路径传递 通过在url后面拼接参数,参数与路径之间使用 ? 分隔,参数键与参数值用 相连,不同参数用 & 分隔;如…...
OPC DA 客户端与服务器的那点事
C#开发OPC客户端,使用OPCDAAuto.dll。在开发过程中偶遇小坎坷,主要记录一下问题解决办法。 1、建立客户端,参考链接。建立WinFrom工程,将博客中代码全部复制即可运行: https://www.cnblogs.com/kjgagaga/p/17011730.…...
Java 错误异常介绍(Exceptions)
1、异常介绍 异常是程序执行期间发生的意外事件。它影响程序指令流,从而导致程序异常终止。 发生异常的原因有很多。其中包括: 无效的用户输入 设备故障 网络连接丢失 物理限制(磁盘内存不足) 代码错误 打开一个不可用的文…...
每日一题——旋转数组的最小数字
题目 有一个长度为 n 的非降序数组,比如[1,2,3,4,5],将它进行旋转,即把一个数组最开始的若干个元素搬到数组的末尾,变成一个旋转数组,比如变成了[3,4,5,1,2],或者[4,5,1,2,3]这样的。请问,给定这…...
SpringBoot Jackson 日期格式化统一配置
目录 1.在全局配置文件配置 2.通过JavaBean方式配置 1.在全局配置文件配置 spring:jackson:date-format: yyyy-MM-dd HH:mm:sstime-zone: GMT8 该配置方式仅支持 Date 类型的日期格式化,不支持LocalDate 及 LocalDateTime 的格式化。 2.通过JavaBean方式配置 …...
剑指 Offer 38. 字符串的排列 / LeetCode 47. 全排列 II(回溯法)
题目: 链接:剑指 Offer 38. 字符串的排列 难度:中等 输入一个字符串,打印出该字符串中字符的所有排列。 你可以以任意顺序返回这个字符串数组,但里面不能有重复元素。 示例: 输入:s “abc” 输出&…...
【前端知识】React 基础巩固(四十三)——Effect Hook
React 基础巩固(四十三)——Effect Hook 一、Effect Hook的基本使用 Effect Hook 用来完成一些类似class中生命周期的功能。 在使用类组件时,不管是渲染、网路请求还是操作DOM,其逻辑和代码是杂糅在一起的。例如我们希望把计数器结果显示在标签上&…...
一百三十八、ClickHouse——使用clickhouse-backup备份ClickHouse库表
一、目标 使用clickhouse-backup在本地全库备份ClickHouse的数据库 二、前提 已经安装好clickhouse-backup 注意:由于之前同事已经按照好clickhouse-backup,所以我就没有安装 如有需要请参考其他人的博客安装一下,下面是我认为比较好的一…...
【无标题】使用Debate Dynamics在知识图谱上进行推理(2020)7.31
使用Debate Dynamics在知识图谱上进行推理 摘要介绍背景与相关工作我们的方法 摘要 我们提出了一种新的基于 Debate Dynamics 的知识图谱自动推理方法。 其主要思想是将三重分类任务定义为两个强化学习主体之间的辩论游戏,这两个主体提取论点(知识图中…...
windows下若依vue项目部署
下载若依项目,前端后端项目本地启动前端打包,后端打包配置nginx.conf 需要注意的是:路径别用中文,要不然报错 #前台访问地址及端口80,在vue.config.js中可查看server {listen 80;server_name localhost; #后台…...
【目标检测】基于yolov5的水下垃圾检测(附代码和数据集,7684张图片)
写在前面: 首先感谢兄弟们的订阅,让我有创作的动力,在创作过程我会尽最大能力,保证作品的质量,如果有问题,可以私信我,让我们携手共进,共创辉煌。 路虽远,行则将至;事虽难,做则必成。只要有愚公移山的志气、滴水穿石的毅力,脚踏实地,埋头苦干,积跬步以至千里,就…...
业务系统对接大模型的基础方案:架构设计与关键步骤
业务系统对接大模型:架构设计与关键步骤 在当今数字化转型的浪潮中,大语言模型(LLM)已成为企业提升业务效率和创新能力的关键技术之一。将大模型集成到业务系统中,不仅可以优化用户体验,还能为业务决策提供…...
Cursor实现用excel数据填充word模版的方法
cursor主页:https://www.cursor.com/ 任务目标:把excel格式的数据里的单元格,按照某一个固定模版填充到word中 文章目录 注意事项逐步生成程序1. 确定格式2. 调试程序 注意事项 直接给一个excel文件和最终呈现的word文件的示例,…...
【解密LSTM、GRU如何解决传统RNN梯度消失问题】
解密LSTM与GRU:如何让RNN变得更聪明? 在深度学习的世界里,循环神经网络(RNN)以其卓越的序列数据处理能力广泛应用于自然语言处理、时间序列预测等领域。然而,传统RNN存在的一个严重问题——梯度消失&#…...
学校时钟系统,标准考场时钟系统,AI亮相2025高考,赛思时钟系统为教育公平筑起“精准防线”
2025年#高考 将在近日拉开帷幕,#AI 监考一度冲上热搜。当AI深度融入高考,#时间同步 不再是辅助功能,而是决定AI监考系统成败的“生命线”。 AI亮相2025高考,40种异常行为0.5秒精准识别 2025年高考即将拉开帷幕,江西、…...
10-Oracle 23 ai Vector Search 概述和参数
一、Oracle AI Vector Search 概述 企业和个人都在尝试各种AI,使用客户端或是内部自己搭建集成大模型的终端,加速与大型语言模型(LLM)的结合,同时使用检索增强生成(Retrieval Augmented Generation &#…...
处理vxe-table 表尾数据是单独一个接口,表格tableData数据更新后,需要点击两下,表尾才是正确的
修改bug思路: 分别把 tabledata 和 表尾相关数据 console.log() 发现 更新数据先后顺序不对 settimeout延迟查询表格接口 ——测试可行 升级↑:async await 等接口返回后再开始下一个接口查询 ________________________________________________________…...
AI+无人机如何守护濒危物种?YOLOv8实现95%精准识别
【导读】 野生动物监测在理解和保护生态系统中发挥着至关重要的作用。然而,传统的野生动物观察方法往往耗时耗力、成本高昂且范围有限。无人机的出现为野生动物监测提供了有前景的替代方案,能够实现大范围覆盖并远程采集数据。尽管具备这些优势…...
uniapp 开发ios, xcode 提交app store connect 和 testflight内测
uniapp 中配置 配置manifest 文档:manifest.json 应用配置 | uni-app官网 hbuilderx中本地打包 下载IOS最新SDK 开发环境 | uni小程序SDK hbulderx 版本号:4.66 对应的sdk版本 4.66 两者必须一致 本地打包的资源导入到SDK 导入资源 | uni小程序SDK …...
计算机基础知识解析:从应用到架构的全面拆解
目录 前言 1、 计算机的应用领域:无处不在的数字助手 2、 计算机的进化史:从算盘到量子计算 3、计算机的分类:不止 “台式机和笔记本” 4、计算机的组件:硬件与软件的协同 4.1 硬件:五大核心部件 4.2 软件&#…...
Unity中的transform.up
2025年6月8日,周日下午 在Unity中,transform.up是Transform组件的一个属性,表示游戏对象在世界空间中的“上”方向(Y轴正方向),且会随对象旋转动态变化。以下是关键点解析: 基本定义 transfor…...
