C语言设计模式:实现简单工厂模式和工程创建

news/2024/5/3 19:02:54/文章来源:https://blog.csdn.net/m0_74985965/article/details/129375133

目录

一,设计模式概念引入

① 什么是设计模式

② 什么是类和对象

③ 什么是工厂模式

二,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 

 

 

 

 

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

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

相关文章

水库大坝安全监测及水情自动测报系统(设备清单)

解决方案水库大坝安全监测及水情自动测报系统方案&#xff0c;系统主要由降雨量监测站、水库水位监测站、大坝安全监测中的渗流量、渗流压力和变形监测站及视频和图像监测站等站点组成&#xff0c;同时建立规范、统一的监测平台&#xff0c;集数据传输、信息共享、数据储存于一…

【黄河流域公安院校网络空间安全技能挑战赛】部分wp

文章目录webbabyPHPfunnyPHPEzphp**遍历文件目录的类**1、DirectoryIterator&#xff1a;2、FilesystemIterator:3、**Globlterator**读取文件内容的类&#xff1a;SplFileObjectMisc套娃web babyPHP <?php highlight_file(__FILE__); error_reporting(0);$num $_GET[nu…

小程序技术如何提升企业的移动研发效率?

随着移动互联网的普及&#xff0c;移动应用程序已成为企业营销和服务的重要途径。随着技术的不断发展和革新&#xff0c;移动应用程序的开发方式也在不断地演变。 一些技术趋势 1、跨平台开发 跨平台开发已成为移动应用程序开发的趋势。根据 Statista 的报告&#xff0c;截至…

matplotlib: 绘制柱状图

通过matplotlib绘制柱形图 第一个例子 from matplotlib import pyplot as plty [10, 11, 12, 11, 9, 8, 13, 10] # 创建y轴坐标 x list(range(1,9)) # 创建x轴坐标# 创建x轴显示的参数&#xff08;此功能在与在图像中x轴仅显示能被10整除的刻度&#xff0c;避免刻度过多分…

概率论小课堂:泊松分布(完善你对随机性的认识,特别是对风险防范的认识)

文章目录引言I 泊松分布1.1 概率计算公式1.2 应对随机性&#xff0c;需要的冗余比平均值要大1.3 池子越大&#xff0c;越能抵消随机性带来的误差引言 伯努利试验&#xff1a;解释了随机事件的发生概率在理论和现实中的差距泊松分布&#xff1a;进一步完善你对随机性的认识&…

OpenCV各模块函数使用实例(11)--- 矩阵和数组操作(Operations on arrays)

OpenCV各模块函数使用实例&#xff08;11&#xff09;M、矩阵和数组操作&#xff08;Operations on arrays&#xff09;本节描述矩阵的基本操作&#xff0c;这些操作是图像处理和其他数组算法实现的基本操作&#xff0c;包括矩阵的运算&#xff0c;特征值和特征向量&#xff0c…

react router零基础使用教程

安装既然学习 react router 就免不了运行 react安装 reactnpx create-react-app my-appcd my-appnpm start安装 react routernpm install react-router-dom如果一切正常&#xff0c;就让我们打开 index.js 文件。配置路由引入 react-router-dom 的 RouterProviderimport {Route…

RTOS中的消息队列的原理以及应用

消息队列的原理 RTOS中的消息队列是一种用于任务间通信的机制&#xff0c;它可以实现任务之间的异步通信&#xff0c;从而实现任务间的解耦。消息队列是一个先进先出的数据结构&#xff0c;任务可以向队列中发送消息&#xff0c;也可以从队列中接收消息。 消息队列的原理如下…

Web3中的营销:如何在2023年获得优势

Mar. 2022, Daniel在过去的一年里&#xff0c;让人们对你的Web3项目或协议感兴趣已经变得越来越有挑战性。许多曾经充满希望的项目因为各种不同的原因&#xff0c;都在熊市中倒下了。然而&#xff0c;那些迄今为止幸存下来的项目都有一个共同点&#xff1a;强大的社区。Web3营销…

Spark 平衡 CPU

Spark 平衡 CPUCPU/内存平衡CPU 低效线程挂起调度开销优化 CPUCPU/内存平衡 Spark 将内存分 : Execution Memory : 用于分布式任务执行Storage Memory : 用于 RDD 缓存RDD 缓存展开前消耗 Execution Memory , 最后占用 Storage Memory 线程/执行内存关系&#xff1a; 执行内…

2.3 二分搜索技术

二分搜索算法是运用分治策略的典型例子。给定己排好府的 n个元素a10:n-1]&#xff0c;现要在这n个元素中找出一特定元素3。首先较容易想到的是用顺序搜索方法&#xff0c;逐个比较a10:1-1]中元素&#xff0c;直至找出元素&#xff0c;或搜索遍整个数组后确定&#xff0c;不在其…

字节3次都没裁掉的7年老测试。掌握设计业务与技术方案,打开上升通道!

前言职场中的那些魔幻操作&#xff0c;研发最烦的是哪个&#xff1f;“面对业务需求的时候&#xff0c;可能都听过这样一句话&#xff1a;这个很简单&#xff0c;直接开发&#xff0c;三天内上线&#xff1b;”朋友说&#xff1a;“产品听了流泪&#xff0c;测试见了崩溃&#…

元宇宙、区块链 通俗易懂

什么是区块链&#xff1f;比特币挖矿是什么&#xff1f;元宇宙是什么&#xff1f;Web(万维网)的三权化进化&#xff1a;基于此&#xff0c;介绍下“元宇宙”。1992年&#xff0c;美国作家史蒂芬森在《雪崩》一书中首次提出了“元宇宙(Metaverse)”的概念。元宇宙实际上就是一种…

[Python图像处理] 使用高通滤波器实现同态滤波

使用高通滤波器实现同态滤波同态滤波基础实现同态滤波相关链接同态滤波基础 同态滤波是一种去除图像中乘性噪声的技术&#xff0c;常用于校正图像中的不均匀照明。根据图像形成的光照反射模型&#xff0c;图像 f(x,y)f(x,y)f(x,y) 可以由以下两个分量表征&#xff1a; 入射到…

一篇深入解析BTF 实践指南

BPF 是 Linux 内核中基于寄存器的虚拟机&#xff0c;可安全、高效和事件驱动的方式执行加载至内核的字节码。与内核模块不同&#xff0c;BPF 程序经过验证以确保它们终止并且不包含任何可能锁定内核的循环。BPF 程序允许调用的内核函数也受到限制&#xff0c;以确保最大的安全性…

scratch老鹰捉小鸡 电子学会图形化编程scratch等级考试二级真题和答案解析2022年12月

目录 scratch老鹰捉小鸡 一、题目要求 1、准备工作 2、功能实现 二、案例分析 <

分布式系统中的补偿机制设计问题

我们知道&#xff0c;应用系统在分布式的情况下&#xff0c;在通信时会有着一个显著的问题&#xff0c;即一个业务流程往往需要组合一组服务&#xff0c;且单单一次通信可能会经过 DNS 服务&#xff0c;网卡、交换机、路由器、负载均衡等设备&#xff0c;而这些服务于设备都不一…

使用flex弹性造APP首页轮子【前端Flex弹性布局】

文章目录一.使用flex弹性造一个APP首页轮子二.需求分析和完成步骤三.效果预览:一.使用flex弹性造一个APP首页轮子 这是内科大企业课(全栈开发_web前端的课程)&#xff0c;需求如下&#xff1a; 使用Flex弹性布局&#xff0c;仿写下面的页面&#xff1a; 二.需求分析和完成步…

Ubuntu系统升级16.04升级18.04

一、需求说明 作为Linux发行版中的后起之秀&#xff0c;Ubuntu 在短短几年时间里便迅速成长为从Linux初学者到实验室用计算机/服务器都适合使用的发行版&#xff0c;目前官网最新版本是22.04。Ubuntu16.04是2016年4月发行的版本&#xff0c;于2019年4月停止更新维护。很多软件支…

剑指 Offer 58 - 翻转单词顺序

摘要 剑指 Offer 58 - I. 翻转单词顺序 一、双指针解析 算法解析&#xff1a; 倒序遍历字符串s &#xff0c;记录单词左右索引边界i , j&#xff1b;每确定一个单词的边界&#xff0c;则将其添加至单词列表res&#xff1b;最终&#xff0c;将单词列表拼接为字符串&#xff…