当前位置: 首页 > news >正文

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语言设计模式:实现简单工厂模式和工程创建

目录 一&#xff0c;设计模式概念引入 ① 什么是设计模式 ② 什么是类和对象 ③ 什么是工厂模式 二&#xff0c;C语言工厂模式的实现 ① 普通类和对象的代码实现 ② 工厂模式代码实现 ● cat.c ● dog.c ● person.c ● animal.h ● mainpro.c ● 完善mainpro.c …...

3.6日报

今天进行3.0信号整理工作 做官网后台技术文档 了解grpc gRPC是rpc框架中的一种&#xff0c;是rpc中的大哥 是一个高性能&#xff0c;开源和通用的RPC框架&#xff0c;基于Protobuf序列化协议开发&#xff0c;且支持众多开发语言。 面向服务端和协议端&#xff0c;基于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 基础(五)之 映射

目录前言一、映射&#xff08;Mapping&#xff09;简介二、动态映射&#xff08;Dynamic mapping&#xff09;1、动态字段映射1.1、日期检测1.1.1、禁用日期检测1.1.2、自定义检测到的日期格式1.2、数值检测2、动态模板三、显示映射&#xff08;Explicit mapping&#xff09;1、…...

【C语言督学训练营 第二天】C语言中的数据类型及标准输入输出

文章目录一、前言二、数据类型1.基本数据类型①.整形②.浮点型③.字符型2.高级数据类型3.数据分类①.常量②.变量三、标准输入输出1.scanf2.printf四、进制转换1.进制转换简介2.十进制转其他进制3.其他进制转换五、OJ网站的使用一、前言 王道2024考研408C语言督学营第二天&…...

重资产模式和物流网络将推动京东第四季度利润率增长

来源&#xff1a;猛兽财经 作者&#xff1a;猛兽财经 强劲的2022年第三季度财务业绩 2022年11月18日&#xff0c;京东&#xff08;JD&#xff09;公布了2022年第三季度财务业绩&#xff0c;净收入为2435亿元人民币&#xff0c;增长了11.4%。净服务收入为465亿元人民币&#xf…...

【新】EOS至MES的假捻报工数据导入-V2.0版本

假捻自动线的数据和MES没有进行对接,直接入库至EOS。 因此可信平台上缺少这部分的报工数据,需要把EOS的入库数据导出,整理成报工数据,导入到MES,然后通过定时任务集成到可信平台。 MES这边的报工数据整理,主要是添加订单明细ID,和完工单号。 订单明细ID(根据批次号和…...

python甜橙歌曲音乐网站平台源码

wx供重浩&#xff1a;创享日记 对话框发送&#xff1a;python音乐 获取完整源码源文件说明文档配置教程等 在虚拟环境下输入命令“python manage.py runserver”启动项目&#xff0c;启动成功后&#xff0c;访问“http://127.0.0.1:5000”进入甜橙音乐网首页&#xff0c;如图1所…...

docker imageID计算

Image ID是在本地由Docker根据镜像的描述文件计算的&#xff0c;并用于imagedb的目录名称 docker镜像id都保存在/var/lib/docker/image/overlay2/imagedb/content/sha256下面&#xff0c;都是一些以sha256sum计算文件内容得出的哈希值的文件。 #ls /var/lib/docker/image/ove…...

借助媛如意让ROS机器人turtlesim画出美丽的曲线-云课版本

首先安装并打开猿如意其次打开蓝桥云课ROS并加入课程在猿如意输入问题得到答案在蓝桥云课ROS验证如何通过turtlesim入门ROS机器人您可以通过以下步骤入门ROS机器人&#xff1a;安装ROS&#xff1a;您需要安装ROS&#xff0c;可以在ROS官网上找到安装指南。安装turtlesim&#x…...

小区业主入户安检小程序开发

小区业主入户安检小程序开发 可针对不同行业自定义安检项目&#xff0c;线下安检&#xff0c;线上留存&#xff08;安检拍照/录像&#xff09;&#xff0c;提高安检人员安检效率 功能特性&#xff0c;为你介绍小区入户安检系统的功能特性。 小区管理;后台可添加需要安检的小区…...

【C++知识点】异常处理

✍个人博客&#xff1a;https://blog.csdn.net/Newin2020?spm1011.2415.3001.5343 &#x1f4da;专栏地址&#xff1a;C/C知识点 &#x1f4e3;专栏定位&#xff1a;整理一下 C 相关的知识点&#xff0c;供大家学习参考~ ❤️如果有收获的话&#xff0c;欢迎点赞&#x1f44d;…...

【FATE联邦学习debug】 No module named ‘federatedml‘

直接pip install federatedml是无法找得到这个库的。 这个的原因是环境变量的事情&#xff0c;因为在部署文档中&#xff0c;本身提示我们要更新一些环境变量&#xff0c;如果不export那些变量&#xff0c;下面的fate_test其实也是无法测试成功的。 打开bin/init_env.sh&#x…...

【Git】P1 Git 基础

Git 基础Git 基本概念集中式版本控制工具 与 分布式版本控制工具Git 下载与安装Bash 初始设置创建本地仓库Git 三区概念一个简单的提交流程更改文件后再次提交git 实现版本切换查看提交日志设置 git 快捷键版本切换&#xff08;一&#xff09;版本切换&#xff08;二&#xff0…...

智能交通数据集Rope3D(仅限科研使用)

Rope3D Dataset 官网&#xff1a;https://thudair.baai.ac.cn/index &#xff01;&#xff01;&#xff01;如想要使用Rope3D数据集进行2D检测&#xff0c;最后有我们处理完的数据集链接。 &#xff01;&#xff01;&#xff01; 介绍&#xff1a; DAIR-V2X数据集是首个用于…...

Java虚拟机JVM-面试题

1、Java 虚拟机是如何捕获异常的&#xff1f; 答&#xff1a; 在编译生成的字节码中&#xff0c;每个方法都附带一个异常表。异常表中的每一个条目代表一个异常处理器&#xff0c;并且由 from 指针、to 指针、target 指针以及所捕获的异常类型构成。这些指针的值是字节码索引…...

详细的说说Redis的数据类型

Redis是一个开源的内存数据库&#xff0c;它可以用作缓存、消息代理、实时数据处理和许多其他用途。Redis是一个key-value存储系统&#xff0c;其中数据存储在内存中&#xff0c;并通过网络进行访问。与传统的关系型数据库不同&#xff0c;Redis支持多种数据结构&#xff0c;包…...

798.差分矩阵

输入一个 n行 m列的整数矩阵&#xff0c;再输入 q个操作&#xff0c;每个操作包含五个整数 x1,y1,x2,y2,c&#xff0c;其中 (x1,y1)和 (x2,y2) 表示一个子矩阵的左上角坐标和右下角坐标。每个操作都要将选中的子矩阵中的每个元素的值加上 c。 请你将进行完所有操作后的矩阵输出…...

InfluxDB 2 介绍与使用 flux查询 数据可视化

一、关键概念 相比V1 移除了database 和 RP&#xff0c;增加了bucket。 V2具有以下几个概念&#xff1a; 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: 用于显示树状结构数据&#xff0c;适用于树状结构数据的操作。 一、初始化 ​ 利用QStandardlternModel来初始化数据&#xff0c;标准的基于项数据的数据模型类&#xff0c; 每个项数据可以是任何数据类型。 // 初始化model QStandardItem…...

Day131 | 灵神 | 回溯算法 | 子集型 子集

Day131 | 灵神 | 回溯算法 | 子集型 子集 78.子集 78. 子集 - 力扣&#xff08;LeetCode&#xff09; 思路&#xff1a; 笔者写过很多次这道题了&#xff0c;不想写题解了&#xff0c;大家看灵神讲解吧 回溯算法套路①子集型回溯【基础算法精讲 14】_哔哩哔哩_bilibili 完…...

将对透视变换后的图像使用Otsu进行阈值化,来分离黑色和白色像素。这句话中的Otsu是什么意思?

Otsu 是一种自动阈值化方法&#xff0c;用于将图像分割为前景和背景。它通过最小化图像的类内方差或等价地最大化类间方差来选择最佳阈值。这种方法特别适用于图像的二值化处理&#xff0c;能够自动确定一个阈值&#xff0c;将图像中的像素分为黑色和白色两类。 Otsu 方法的原…...

基于Docker Compose部署Java微服务项目

一. 创建根项目 根项目&#xff08;父项目&#xff09;主要用于依赖管理 一些需要注意的点&#xff1a; 打包方式需要为 pom<modules>里需要注册子模块不要引入maven的打包插件&#xff0c;否则打包时会出问题 <?xml version"1.0" encoding"UTF-8…...

C++ 求圆面积的程序(Program to find area of a circle)

给定半径r&#xff0c;求圆的面积。圆的面积应精确到小数点后5位。 例子&#xff1a; 输入&#xff1a;r 5 输出&#xff1a;78.53982 解释&#xff1a;由于面积 PI * r * r 3.14159265358979323846 * 5 * 5 78.53982&#xff0c;因为我们只保留小数点后 5 位数字。 输…...

Java + Spring Boot + Mybatis 实现批量插入

在 Java 中使用 Spring Boot 和 MyBatis 实现批量插入可以通过以下步骤完成。这里提供两种常用方法&#xff1a;使用 MyBatis 的 <foreach> 标签和批处理模式&#xff08;ExecutorType.BATCH&#xff09;。 方法一&#xff1a;使用 XML 的 <foreach> 标签&#xff…...

Kafka入门-生产者

生产者 生产者发送流程&#xff1a; 延迟时间为0ms时&#xff0c;也就意味着每当有数据就会直接发送 异步发送API 异步发送和同步发送的不同在于&#xff1a;异步发送不需要等待结果&#xff0c;同步发送必须等待结果才能进行下一步发送。 普通异步发送 首先导入所需的k…...

深度学习水论文:mamba+图像增强

&#x1f9c0;当前视觉领域对高效长序列建模需求激增&#xff0c;对Mamba图像增强这方向的研究自然也逐渐火热。原因在于其高效长程建模&#xff0c;以及动态计算优势&#xff0c;在图像质量提升和细节恢复方面有难以替代的作用。 &#x1f9c0;因此短时间内&#xff0c;就有不…...

腾讯云V3签名

想要接入腾讯云的Api&#xff0c;必然先按其文档计算出所要求的签名。 之前也调用过腾讯云的接口&#xff0c;但总是卡在签名这一步&#xff0c;最后放弃选择SDK&#xff0c;这次终于自己代码实现。 可能腾讯云翻新了接口文档&#xff0c;现在阅读起来&#xff0c;清晰了很多&…...

PHP 8.5 即将发布:管道操作符、强力调试

前不久&#xff0c;PHP宣布了即将在 2025 年 11 月 20 日 正式发布的 PHP 8.5&#xff01;作为 PHP 语言的又一次重要迭代&#xff0c;PHP 8.5 承诺带来一系列旨在提升代码可读性、健壮性以及开发者效率的改进。而更令人兴奋的是&#xff0c;借助强大的本地开发环境 ServBay&am…...

【前端异常】JavaScript错误处理:分析 Uncaught (in promise) error

在前端开发中&#xff0c;JavaScript 异常是不可避免的。随着现代前端应用越来越多地使用异步操作&#xff08;如 Promise、async/await 等&#xff09;&#xff0c;开发者常常会遇到 Uncaught (in promise) error 错误。这个错误是由于未正确处理 Promise 的拒绝&#xff08;r…...