C语言设计模式:实现简单工厂模式和工程创建
目录
一,设计模式概念引入
① 什么是设计模式
② 什么是类和对象
③ 什么是工厂模式
二,C语言工厂模式的实现
① 普通类和对象的代码实现
② 工厂模式代码实现
● cat.c
● dog.c
● person.c
● animal.h
● mainpro.c
● 完善mainpro.c
三,使用Source insight4.0创建工程
一,设计模式概念引入
① 什么是设计模式
设计模式通常被面向对象的软件开发人员所采用,是软件开发人员在软件开发过程中面临问题的解决方案。也是众多软件开发人员经过长时间的试验和错误总结出来的23种设计模式。虽然很多人认为C语言只是面向过程的开发,但鄙人认为此说法并不全面,难道面向对象的语言就不面向过程了吗?同理,在C语言的使用过程中一样允许面向对象。在平时代码编写中,有时会遇到修改一处BUG而影响整个代码的运行,设计模式的出现正好就解决了这一问题。
● 设计模式是建筑设计领域引入到计算机科学中来的;
● 设计模式是对面向对象设计中反复出现的问题的解决方案;
● 算法不是设计模式,因为算法致力于解决问题而非设计问题;
● 设计模式通常描述了一组相互紧密作用的类与对象;
● 设计模式使代码更稳定,更安全,拓展性更强,同时也方便代码重构。
② 什么是类和对象
| C语言 | 面向过程 | 也可以面向对象,还能用其设计模式,只是不太友好的面向对象 |
| Java | 面向对象 | 也可以面向过程,只是不太友好的面向过程 |
| 面向过程和面向对象只是代码的一种编程方式和编程思想,不应该和编程语言绑定起来 | ||
类:类是面对对象程序设计实现信息封装的基础。类是一种用户定义的引用数据类型,也称类类型。比如C语言中结构体,就是用户自己定义的一种数据类型
struct Animal{int age;int sex; //成员属性void (*peat)(); //函数指针void (*pbeat)(); //成员方法
};
对象:类的一种具象。每个类包含数据说明和一组操作数据或传递消息的函数。类的实例就称为对象。
● dog是类Animal的一种具体对象;
● cat是类Animal的一种具体对象;
● person是类Animal的一种具体对象;
struct Animal dog;
struct Animal cat;
struct Animal person;
③ 什么是工厂模式
● 工厂模式是最常用的设计模式之一。这种类型的设计模式属于创建型模式,它提供了一种创建对象的(最佳)方式;
● 在工厂模式中,我们在创建对象时不会对客户端暴露创建逻辑,并且是通过使用一个共同的接口来指向新创建的对象;
● 共同的接口:我们自己创建共同接口API,从工厂里面获得需要的对象放入main函数中去运行。

二,C语言工厂模式的实现
① 普通类和对象的代码实现
#include <stdio.h>/*类:struct Animal*/
/*对象:struct Animal dog/cat/person*/struct Animal{char name[128];int age;int sex; //成员属性void (*peat)();void (*pbeat)(); //成员方法
};void dogeat()
{printf("狗吃屎\n");
}
void cateat()
{printf("猫吃鱼\n");
}
void personeat()
{printf("人吃米\n");
}void dogbeat()
{printf("咬\n");
}
void catbeat()
{printf("挠\n");
}
void personbeat()
{printf("揍\n");
}int main()
{struct Animal dog = {.peat = dogeat,.pbeat = dogbeat};struct Animal cat = {.peat = cateat,.pbeat = catbeat};struct Animal person = { .peat = personeat, //对象,事务的具象.pbeat = personbeat}; dog.peat();cat.peat();person.peat();dog.pbeat();cat.pbeat();person.pbeat();return 0;
}

② 工厂模式代码实现
● 工厂模式不会暴露创建对象的代码逻辑,上面对象代码逻辑全部暴露无遗;
● 以上面的代码为例,以工厂模式的方式将dog,cat,person这几个对象拆分成单独的代码文件,并在每个文件中提供用来链接的函数,方便main函数的调用;

分别创建需要的文件:

● cat.c
#include "animal.h" //自己定义的头文件用双引号void cateat()
{printf("猫吃鱼\n");
}
void catbeat()
{printf("挠\n");
}struct Animal cat = {.name = "Tom",.peat = cateat,.pbeat = catbeat
};struct Animal* putCatInLink(struct Animal *phead) //头插法,会改变头,所以用到指针
{ //链表头传过来if(phead == NULL){ //如果头为空,那就返回cat为链表头 return &cat;}else{ cat.next = phead; //否者cat的下一个为链头phead = &cat; //再把链头指向猫return phead;}
};
● dog.c
#include "animal.h"void dogeat()
{printf("狗吃屎\n");
}void dogbeat()
{printf("咬\n");
}struct Animal dog = {.name = "huang",.peat = dogeat,.pbeat = dogbeat};struct Animal* putDogInLink(struct Animal *phead)
{if(phead == NULL){return &dog;}else{dog.next = phead;phead = &dog;return phead;}
};
● person.c
#include "animal.h"void personeat()
{printf("人吃米\n");
}void personbeat()
{printf("揍\n");
}struct Animal person = { .name = "xiaomin",.peat = personeat, //对象,事务的具象.pbeat = personbeat};struct Animal* putPersonInLink(struct Animal *phead)
{if(phead == NULL){return &person;}else{person.next = phead;phead = &person;return phead;}
};
● animal.h
#include <stdio.h>struct Animal{char name[128];int age;int sex; //成员属性void (*peat)();void (*pbeat)(); //成员方法struct Animal *next; //涉及到链表,添加链表节点
};struct Animal* putCatInLink(struct Animal *phead); //cat.c文件中的该函数将cat相关全局的结构体加到链表中
struct Animal* putDogInLink(struct Animal *phead);//dog.c文件中的该函数将dog相关全局的结构体加到链表中
struct Animal* putPersonInLink(struct Animal *phead);//person.c文件中的该函数将person相关全局的结构体加到链表中
● mainpro.c
#include "animal.h"int main()
{struct Animal *phead = NULL;//初始化phead = putCatInLink(phead);phead = putDogInLink(phead);phead = putPersonInLink(phead);return 0;
}
编译说明: 多个.c文件同时编译:gcc *.c , 如果编译过程中没有报错,但是没有输出内容,是因为在manpro.c的代码中没有输出代码,但是链接成功

● 完善mainpro.c
#include "animal.h"
#include <string.h>struct Animal *findUtilByName(char *str,struct Animal *phead){struct Animal *tmp = phead;if(phead == NULL){printf("空\n");return NULL;}else{while(tmp != NULL){ //遍历链表if(strcmp(tmp->name,str) == 0){ //tmp的值和输入的名字是相等的,说明找到了return tmp;} tmp = tmp->next; //没找到的话就继续遍历链表}return NULL;//一直没找到就返回NULL}
}
int main()
{char buf[128] = {'\0'};struct Animal *phead = NULL;//初始化struct Animal *ptmp;phead = putCatInLink(phead);phead = putDogInLink(phead);phead = putPersonInLink(phead);while(1){printf("请输入:Tom,haung,xiaomin\n");scanf("%s",buf);ptmp = findUtilByName(buf,phead);//根据用户输入的名字,找到相应的结构体if(ptmp != NULL){ptmp->pbeat();ptmp->peat();}memset(buf,'\0',sizeof(buf)); }return 0;
}
编译结果: C语言简单工厂模式完成!

三,使用Source insight4.0创建工程
目的:同时阅读多个文件时更加方便,高效,便于后起维护和管理


打开source insight





相关文章:
C语言设计模式:实现简单工厂模式和工程创建
目录 一,设计模式概念引入 ① 什么是设计模式 ② 什么是类和对象 ③ 什么是工厂模式 二,C语言工厂模式的实现 ① 普通类和对象的代码实现 ② 工厂模式代码实现 ● cat.c ● dog.c ● person.c ● animal.h ● mainpro.c ● 完善mainpro.c …...
3.6日报
今天进行3.0信号整理工作 做官网后台技术文档 了解grpc gRPC是rpc框架中的一种,是rpc中的大哥 是一个高性能,开源和通用的RPC框架,基于Protobuf序列化协议开发,且支持众多开发语言。 面向服务端和协议端,基于http…...
中文代码88
PK 嘚釦 docProps/PK 嘚釦|,g z docProps/app.xml漅AN??駠(髂v诖m岼侸 魣,g踃$秂D廋Qvf漶x莗笳w?:瘜^?俍欶辇2}?睧汎 t#:?效7治XtA鏊?羄鈋嫿饄攗Tv契"D桷撵vJ鉂?闌 Jg??浱?樱沲gic鋹峡?sū窛葻?]迾?9卑{艏 rk\?洺萹啰N?W??2&quo…...
ElasticSearch 基础(五)之 映射
目录前言一、映射(Mapping)简介二、动态映射(Dynamic mapping)1、动态字段映射1.1、日期检测1.1.1、禁用日期检测1.1.2、自定义检测到的日期格式1.2、数值检测2、动态模板三、显示映射(Explicit mapping)1、…...
【C语言督学训练营 第二天】C语言中的数据类型及标准输入输出
文章目录一、前言二、数据类型1.基本数据类型①.整形②.浮点型③.字符型2.高级数据类型3.数据分类①.常量②.变量三、标准输入输出1.scanf2.printf四、进制转换1.进制转换简介2.十进制转其他进制3.其他进制转换五、OJ网站的使用一、前言 王道2024考研408C语言督学营第二天&…...
重资产模式和物流网络将推动京东第四季度利润率增长
来源:猛兽财经 作者:猛兽财经 强劲的2022年第三季度财务业绩 2022年11月18日,京东(JD)公布了2022年第三季度财务业绩,净收入为2435亿元人民币,增长了11.4%。净服务收入为465亿元人民币…...
【新】EOS至MES的假捻报工数据导入-V2.0版本
假捻自动线的数据和MES没有进行对接,直接入库至EOS。 因此可信平台上缺少这部分的报工数据,需要把EOS的入库数据导出,整理成报工数据,导入到MES,然后通过定时任务集成到可信平台。 MES这边的报工数据整理,主要是添加订单明细ID,和完工单号。 订单明细ID(根据批次号和…...
python甜橙歌曲音乐网站平台源码
wx供重浩:创享日记 对话框发送:python音乐 获取完整源码源文件说明文档配置教程等 在虚拟环境下输入命令“python manage.py runserver”启动项目,启动成功后,访问“http://127.0.0.1:5000”进入甜橙音乐网首页,如图1所…...
docker imageID计算
Image ID是在本地由Docker根据镜像的描述文件计算的,并用于imagedb的目录名称 docker镜像id都保存在/var/lib/docker/image/overlay2/imagedb/content/sha256下面,都是一些以sha256sum计算文件内容得出的哈希值的文件。 #ls /var/lib/docker/image/ove…...
借助媛如意让ROS机器人turtlesim画出美丽的曲线-云课版本
首先安装并打开猿如意其次打开蓝桥云课ROS并加入课程在猿如意输入问题得到答案在蓝桥云课ROS验证如何通过turtlesim入门ROS机器人您可以通过以下步骤入门ROS机器人:安装ROS:您需要安装ROS,可以在ROS官网上找到安装指南。安装turtlesim&#x…...
小区业主入户安检小程序开发
小区业主入户安检小程序开发 可针对不同行业自定义安检项目,线下安检,线上留存(安检拍照/录像),提高安检人员安检效率 功能特性,为你介绍小区入户安检系统的功能特性。 小区管理;后台可添加需要安检的小区…...
【C++知识点】异常处理
✍个人博客:https://blog.csdn.net/Newin2020?spm1011.2415.3001.5343 📚专栏地址:C/C知识点 📣专栏定位:整理一下 C 相关的知识点,供大家学习参考~ ❤️如果有收获的话,欢迎点赞👍…...
【FATE联邦学习debug】 No module named ‘federatedml‘
直接pip install federatedml是无法找得到这个库的。 这个的原因是环境变量的事情,因为在部署文档中,本身提示我们要更新一些环境变量,如果不export那些变量,下面的fate_test其实也是无法测试成功的。 打开bin/init_env.sh&#x…...
【Git】P1 Git 基础
Git 基础Git 基本概念集中式版本控制工具 与 分布式版本控制工具Git 下载与安装Bash 初始设置创建本地仓库Git 三区概念一个简单的提交流程更改文件后再次提交git 实现版本切换查看提交日志设置 git 快捷键版本切换(一)版本切换(二࿰…...
智能交通数据集Rope3D(仅限科研使用)
Rope3D Dataset 官网:https://thudair.baai.ac.cn/index !!!如想要使用Rope3D数据集进行2D检测,最后有我们处理完的数据集链接。 !!! 介绍: DAIR-V2X数据集是首个用于…...
Java虚拟机JVM-面试题
1、Java 虚拟机是如何捕获异常的? 答: 在编译生成的字节码中,每个方法都附带一个异常表。异常表中的每一个条目代表一个异常处理器,并且由 from 指针、to 指针、target 指针以及所捕获的异常类型构成。这些指针的值是字节码索引…...
详细的说说Redis的数据类型
Redis是一个开源的内存数据库,它可以用作缓存、消息代理、实时数据处理和许多其他用途。Redis是一个key-value存储系统,其中数据存储在内存中,并通过网络进行访问。与传统的关系型数据库不同,Redis支持多种数据结构,包…...
798.差分矩阵
输入一个 n行 m列的整数矩阵,再输入 q个操作,每个操作包含五个整数 x1,y1,x2,y2,c,其中 (x1,y1)和 (x2,y2) 表示一个子矩阵的左上角坐标和右下角坐标。每个操作都要将选中的子矩阵中的每个元素的值加上 c。 请你将进行完所有操作后的矩阵输出…...
InfluxDB 2 介绍与使用 flux查询 数据可视化
一、关键概念 相比V1 移除了database 和 RP,增加了bucket。 V2具有以下几个概念: timestamp、field key、field value、field set、tag key、tag value、tag set、measurement、series、point、bucket、bucket schema、organization 新增的概念&…...
Qt QTreeView简单使用
QT-QTreeView使用方法 QTreeView: 用于显示树状结构数据,适用于树状结构数据的操作。 一、初始化 利用QStandardlternModel来初始化数据,标准的基于项数据的数据模型类, 每个项数据可以是任何数据类型。 // 初始化model QStandardItem…...
可靠性+灵活性:电力载波技术在楼宇自控中的核心价值
可靠性灵活性:电力载波技术在楼宇自控中的核心价值 在智能楼宇的自动化控制中,电力载波技术(PLC)凭借其独特的优势,正成为构建高效、稳定、灵活系统的核心解决方案。它利用现有电力线路传输数据,无需额外布…...
生成 Git SSH 证书
🔑 1. 生成 SSH 密钥对 在终端(Windows 使用 Git Bash,Mac/Linux 使用 Terminal)执行命令: ssh-keygen -t rsa -b 4096 -C "your_emailexample.com" 参数说明: -t rsa&#x…...
python如何将word的doc另存为docx
将 DOCX 文件另存为 DOCX 格式(Python 实现) 在 Python 中,你可以使用 python-docx 库来操作 Word 文档。不过需要注意的是,.doc 是旧的 Word 格式,而 .docx 是新的基于 XML 的格式。python-docx 只能处理 .docx 格式…...
scikit-learn机器学习
# 同时添加如下代码, 这样每次环境(kernel)启动的时候只要运行下方代码即可: # Also add the following code, # so that every time the environment (kernel) starts, # just run the following code: import sys sys.path.append(/home/aistudio/external-libraries)机…...
LOOI机器人的技术实现解析:从手势识别到边缘检测
LOOI机器人作为一款创新的AI硬件产品,通过将智能手机转变为具有情感交互能力的桌面机器人,展示了前沿AI技术与传统硬件设计的完美结合。作为AI与玩具领域的专家,我将全面解析LOOI的技术实现架构,特别是其手势识别、物体识别和环境…...
永磁同步电机无速度算法--基于卡尔曼滤波器的滑模观测器
一、原理介绍 传统滑模观测器采用如下结构: 传统SMO中LPF会带来相位延迟和幅值衰减,并且需要额外的相位补偿。 采用扩展卡尔曼滤波器代替常用低通滤波器(LPF),可以去除高次谐波,并且不用相位补偿就可以获得一个误差较小的转子位…...
uniapp 集成腾讯云 IM 富媒体消息(地理位置/文件)
UniApp 集成腾讯云 IM 富媒体消息全攻略(地理位置/文件) 一、功能实现原理 腾讯云 IM 通过 消息扩展机制 支持富媒体类型,核心实现方式: 标准消息类型:直接使用 SDK 内置类型(文件、图片等)自…...
Elastic 获得 AWS 教育 ISV 合作伙伴资质,进一步增强教育解决方案产品组合
作者:来自 Elastic Udayasimha Theepireddy (Uday), Brian Bergholm, Marianna Jonsdottir 通过搜索 AI 和云创新推动教育领域的数字化转型。 我们非常高兴地宣布,Elastic 已获得 AWS 教育 ISV 合作伙伴资质。这一重要认证表明,Elastic 作为 …...
Modbus RTU与Modbus TCP详解指南
目录 1. Modbus协议基础 1.1 什么是Modbus? 1.2 Modbus协议历史 1.3 Modbus协议族 1.4 Modbus通信模型 🎭 主从架构 🔄 请求响应模式 2. Modbus RTU详解 2.1 RTU是什么? 2.2 RTU物理层 🔌 连接方式 ⚡ 通信参数 2.3 RTU数据帧格式 📦 帧结构详解 🔍…...
全面解析数据库:从基础概念到前沿应用
在数字化时代,数据已成为企业和社会发展的核心资产,而数据库作为存储、管理和处理数据的关键工具,在各个领域发挥着举足轻重的作用。从电商平台的商品信息管理,到社交网络的用户数据存储,再到金融行业的交易记录处理&a…...
