软件设计模式——工厂模式
软件设计模式——工厂模式
文章目录
- 软件设计模式——工厂模式
- 一、设计模式的认知
- 1.1 什么是软件设计模式:
- 1.2 为什么要学习设计模式:
- 1.3 设计模式的分类:
- 二、工厂模式
- 2.1 工厂模式实例:
一、设计模式的认知
1.1 什么是软件设计模式:
软件设计模式,又称设计模式。它是一套被反复使用、多数人知晓的、经过分类编目的、代码设计经验的总结。使用设计模式是为了可重用代码、让代码更容易被他人理解、保证代码可靠性、程序的重用性。综上:设计模式就是泛指一系列编程的思想,是代码设计经验的总结,基于设计模式来开发代码可以使得程序更加稳定,拓展性更强。
1.2 为什么要学习设计模式:
在以往的项目开发中,不管是 ftp服务器 还是 图像识别智能垃圾桶 又或者更之前的智能小车项目,都没有一个固定的代码开发格式,更多的是根据需求一个个实现功能,虽然有了分文件编程的思想,但是代码整体还是缺乏规整度。尤其是在开发过程中,一个功能的实现经常会导致其他功能出现问题,所以需要学习设计模式,使得代码更加健壮和格式化。
1.3 设计模式的分类:
软件设计模式共有23种,总体来说可以被分为三大类:
- 五种创建型模式:工厂方法模式、抽象工厂模式、单例模式、建造者模式、原型模式。
- 七种结构型模式:适配器模式、装饰器模式、代理模式、外观模式、桥接模式、组合模式、享元模式。
- 十一种行为型模式:策略模式、模板方法模式、观察者模式、迭代子模式、责任链模式、命令模式、备忘录模式、状态模式、访问者模式、中介者模式、解释器模式。
下面我们就来学习创建型模式中的一种:工厂模式。
二、工厂模式
- 工厂模式(Factory Pattern)是程序中最常见的设计模式之一,这种类型的设计模式属于:创建型模式,它提供了一种创建对象的最佳方法。
- 在工厂模式中,我们在创建对象时不会对客户端暴露创建的逻辑,并且是通过使用一个共同的接口来指向一个新创建的对象。
2.1 工厂模式实例:
- .h文件
#ifndef __PEOPLE_H__
#define __PEOPLE_H__#include <stdio.h>struct People {int age;char name[32]; //成员属性void (*ptalk)(); //成员方法struct People *next; //链表
};struct People* ZhangsanInLink(struct People *head);
struct People* LisiInLink(struct People *head);#endif
- People1.c文件
#include "People.h"void Zhangsan_talk() //张三的说话函数
{printf("请多关照,我是张三.\n");
}struct People Zhangsan = { //张三的结构体.age = 25,.name = "Zhangsan",.ptalk = Zhangsan_talk
}; struct People* ZhangsanInLink(struct People *head) //将张三加入链表
{ if(head == NULL){head = &Zhangsan;}else{Zhangsan.next = head;head = &Zhangsan;}return head;
}
- People2.c文件
#include "People.h"void Lisi_talk() //Lisi的说话函数
{printf("请多关照,我是李四.\n");
}struct People Lisi = { //李四的结构体.age = 20,.name = "Lisi",.ptalk = Lisi_talk
}; struct People* LisiInLink(struct People *head) //将Lisi加入链表
{struct People *p = head;if(p == NULL){head = &Lisi;}else{Lisi.next = head;head = &Lisi;}return head;
}
- main.c文件
#include "People.h"
#include <string.h>struct People* FindPeople(struct People *phead, char *name) // 链表查找函数
{struct People *p = phead;while(p != NULL){ // 遍历链表if(strcmp(p->name, name) == 0){ // 找到该人return p; // 返回该人指针}p = p->next;}return NULL; // 没找到该人
}int main()
{char name[32] = {'\0'}; // 姓名struct People *phead = NULL; // 链表头指针struct People *pfind = NULL; // 链表查找指针// 在链表中插入张三节点和李四节点phead = ZhangsanInLink(phead); phead = LisiInLink(phead);if(phead == NULL){printf("链表中没有元素.\n");return 1;}while(1){printf("请输入要查找的姓名:张三、李四(English)\n"); // 循环读取姓名scanf("%s",name); // 输入姓名 if(strcmp(name, "Zhangsan") == 0 || strcmp(name, "Lisi") == 0){ // 找到该人pfind = FindPeople(phead, name); // 查找该人if(pfind == NULL){printf("没有找到该人.\n");}else{ // 找到该人printf("姓名:%s, 年龄:%d\n",pfind->name, pfind->age); // 打印该人信息pfind->ptalk(); // 调用该人的方法}}else{ // 输入错误printf("请输入正确的姓名.\n");}memset(name, '\0', sizeof(name)); // 清空姓名}return 0;
}
从上面的案例可以看出:
- 这就是一个典型的工厂模式代码设计。对于
main.c
,相比于整体其代码量并不多,且不会向用户暴露创建逻辑。 - 结构体
People
就是一个工厂,是一个类;People1
和People2
作为对象以链表的形式存在在工厂中。
main
函数需要做的就是将工厂中的模块组装起来,然后想用哪个就去找到哪个就可以。
从上面的代码结构不难看出,使用工厂模式使得代码更稳定且拓展性更强,如果需要一个新的模块,只需要再创建一个如People3,并将其插入结构体People
中就可以,十分的方便且不会影响到其他的模块。
相关文章:

软件设计模式——工厂模式
软件设计模式——工厂模式 文章目录 软件设计模式——工厂模式一、设计模式的认知1.1 什么是软件设计模式:1.2 为什么要学习设计模式:1.3 设计模式的分类: 二、工厂模式2.1 工厂模式实例: 一、设计模式的认知 1.1 什么是软件设计…...

Apache Druid命令执行(CVE-2021-25646)
漏洞详情: Apache Druid 是用Java编写的面向列的开源分布式数据存储系统,旨在快速获取大量事件数据,并在数据之上提供低延迟查询。 Apache Druid含有能够执行嵌入在各种类型请求中由用户提供的JavaScript代码功能。此功能适用于高度信任环境…...

新的 MathWorks 硬件支持包支持从 MATLAB 和 Simulink 模型到高通 Hexagon 神经处理单元架构的自动化代码生成
MathWorks 今天宣布,推出针对 Qualcomm Hexagon™ 神经处理单元(NPU)的硬件支持包。该处理单元嵌入在 Snapdragon 系列处理器中。MathWorks 硬件支持包,则专门针对 Qualcomm Technologies 的 Hexagon NPU 架构进行优化,…...
gorm.io/sharding:改造,当查询条件中不包含分表键时,从自定义方法中获取对应的表进行查询
项目背景 这篇文章是一种特殊的情形——当查询条件中不包含分表键时,从自定义方法中获取对应的表进行查询。实际项目中并不建议这种用法。 当然,这里只是提供一种思路。这篇文章也是这个系列中的第三篇文章。前两篇文章《基于gorm.io/sharding分表中间…...

【CSS】变量的声明与使用
原生变量root 伪类 原生变量 CSS中我们可以统一设置变量方便页面维护。变量声明的时候,自定义样式变量名之前加上两根连词线 " – " 即可,使用 var() 来引用。声明的变量是有作用域的 ( 比如是在html中声明的变量,那么该变量在html…...

【数学分析笔记】第3章第4节闭区间上的连续函数(1)
3. 函数极限与连续函数 3.4 闭区间上的连续函数 3.4.1 有界性定理 【定理3.4.1】 f ( x ) f(x) f(x)在闭区间 [ a , b ] [a,b] [a,b]上连续,则 f ( x ) f(x) f(x)在闭区间 [ a , b ] [a,b] [a,b]上有界。 【证】用反证法,假设 f ( x ) f(x) f(x)在 [ …...
Mybatis中sql数组为空判断
一、Mybatis xml中的sql通过if语句判定是否为空 <if test"arrays ! null"> </if>上述示例只能判断arrays数组不为null,那如果是个空数组呢 二、Mybatis xml中的sql通过if语句判定数组非空数组 <if test"arrays ! null and arrays.l…...

12.第二阶段x86游戏实战2-CE找基地址
免责声明:内容仅供学习参考,请合法利用知识,禁止进行违法犯罪活动! 本次游戏没法给 内容参考于:微尘网络安全 本人写的内容纯属胡编乱造,全都是合成造假,仅仅只是为了娱乐,请不要…...
笔记整理—内核!启动!—linux应用编程、网络编程部分(3)文件共享与标准IO
文件共享是指同一个文件被多个独立的读写进行操作。同一个文件为同一个inode,同一个pathname也就是同一个静态文件。同时进行操作,打开一个文件未关闭又被另一个操作打开。文件共享的方式可以实现高效的大文件读写。 文件共享的三种方式:①同…...

plt常用函数介绍一
目录 前言plt.figure()plt.subplot()plt.subplots()plt.xticks()plt.xlim() 前言 Matplotlib是Python中的一个库,它是数字的-NumPy库的数学扩展。 Pyplot是Matplotlib模块的基于状态的接口。在Pyplot中可以使用各种图,例如线图,轮廓图&#…...

基于ExtendSim的 电子制造 仿真模型
说明: 此模型表示电路板制造设施。该过程有4个步骤: *焊料制备 *组件放置 *烤箱 *检查 详情: *烤箱的容量为10张卡,但如果烤箱循环开始时仅能处理5张卡,则最多只能处理5张。 *如果检查员发现问题,他们将修理…...

BGP 路由反射器
转载:BGP 路由反射器 / 实验介绍: / 原理概述 缺省情况下,路由器从它的一个 IBGP 对等体那里接收到的路由条目不会被该路由器再传递给其他IBGP对等体,这个原则称为BGP水平分割 原则,该原则的根本作用是防止 AS 内部的 BGP 路由…...

CSRF高级防御绕过
1)回顾low级别做过csrf页面的密码重置,重复之前的操作,我们发现级别调整中级之后,报错如下 2)检查源码 进入dvwa源码,查找到checktoken: 3)在dvwa-csrf页面上,抓包 http…...

MySQL安装文档-Windows
文章目录 MySQL安装1. 安装2. 配置 MySQL安装 1. 安装 1). 双击官方下来的安装包文件 2). 根据安装提示进行安装 安装MySQL的相关组件,这个过程可能需要耗时几分钟,耐心等待。 输入MySQL中root用户的密码,一定记得记住该密码 2. 配置 安装好MySQL之后…...

html TAB、table生成
1. 代码 <!DOCTYPE html> <head> <meta charset"UTF-8"> <title>Dynamic Tabs with Table Data</title> <style> /* 简单的样式 */ .tab-content { display: none; border: 10px solid #ccc; padding: 30px; mar…...
2024!再见前端!
各位朋友大家晚上好,夜深了,睡不着,想想还是写一篇文章和大家说再见吧! 自2014年入行前端以来,满打满算差不多整整十年了,这十年可以说是见证了中国整个互联网的起飞到全盛时期。这期间经历了电商、金融、…...

【源码+文档+调试讲解】人事管理系统设计与实现Python
摘 要 人事管理系统的目的是让使用者可以更方便的将人、设备和场景更立体的连接在一起。能让用户以更科幻的方式使用产品,体验高科技时代带给人们的方便,同时也能让用户体会到与以往常规产品不同的体验风格。 与安卓,iOS相比较起来ÿ…...

基于注意力机制的图表示学习:GRAPH-BERT模型
人工智能咨询培训老师叶梓 转载标明出处 图神经网络(GNNs)在处理图结构数据方面取得了显著的进展,但现有模型在深层结构中存在性能问题,如“悬挂动画问题”和“过平滑问题”。而且图数据内在的相互连接特性限制了大规模图输入的并…...

linux服务器安装原生的php环境
在CentOS上安装原生的PHP环境相对简单。下面是一个详细的步骤指南,适用于CentOS 7及更高版本。 ### 第一步:更新系统 首先,确保你的系统是最新的: sudo yum update -y ### 第二步:安装EPEL和Remi仓库 1. **安装EP…...

数电学习基础(逻辑门电路+)
1.逻辑门电路 1.1逻辑门电路的简介 1.1.1各种逻辑门电路的简介 基本概念 (1)实现基本逻辑运算和常用逻辑运算的电路称为逻辑门电路,简称门电路。逻辑门电路是组成各种数字电路的基本单元电路。将构成门电路的元器件制作一块半导体芯片上再…...
Golang 面试经典题:map 的 key 可以是什么类型?哪些不可以?
Golang 面试经典题:map 的 key 可以是什么类型?哪些不可以? 在 Golang 的面试中,map 类型的使用是一个常见的考点,其中对 key 类型的合法性 是一道常被提及的基础却很容易被忽视的问题。本文将带你深入理解 Golang 中…...

linux arm系统烧录
1、打开瑞芯微程序 2、按住linux arm 的 recover按键 插入电源 3、当瑞芯微检测到有设备 4、松开recover按键 5、选择升级固件 6、点击固件选择本地刷机的linux arm 镜像 7、点击升级 (忘了有没有这步了 估计有) 刷机程序 和 镜像 就不提供了。要刷的时…...
镜像里切换为普通用户
如果你登录远程虚拟机默认就是 root 用户,但你不希望用 root 权限运行 ns-3(这是对的,ns3 工具会拒绝 root),你可以按以下方法创建一个 非 root 用户账号 并切换到它运行 ns-3。 一次性解决方案:创建非 roo…...
HTML前端开发:JavaScript 常用事件详解
作为前端开发的核心,JavaScript 事件是用户与网页交互的基础。以下是常见事件的详细说明和用法示例: 1. onclick - 点击事件 当元素被单击时触发(左键点击) button.onclick function() {alert("按钮被点击了!&…...
06 Deep learning神经网络编程基础 激活函数 --吴恩达
深度学习激活函数详解 一、核心作用 引入非线性:使神经网络可学习复杂模式控制输出范围:如Sigmoid将输出限制在(0,1)梯度传递:影响反向传播的稳定性二、常见类型及数学表达 Sigmoid σ ( x ) = 1 1 +...
ip子接口配置及删除
配置永久生效的子接口,2个IP 都可以登录你这一台服务器。重启不失效。 永久的 [应用] vi /etc/sysconfig/network-scripts/ifcfg-eth0修改文件内内容 TYPE"Ethernet" BOOTPROTO"none" NAME"eth0" DEVICE"eth0" ONBOOT&q…...
MySQL 部分重点知识篇
一、数据库对象 1. 主键 定义 :主键是用于唯一标识表中每一行记录的字段或字段组合。它具有唯一性和非空性特点。 作用 :确保数据的完整性,便于数据的查询和管理。 示例 :在学生信息表中,学号可以作为主键ÿ…...

Golang——9、反射和文件操作
反射和文件操作 1、反射1.1、reflect.TypeOf()获取任意值的类型对象1.2、reflect.ValueOf()1.3、结构体反射 2、文件操作2.1、os.Open()打开文件2.2、方式一:使用Read()读取文件2.3、方式二:bufio读取文件2.4、方式三:os.ReadFile读取2.5、写…...

在 Spring Boot 中使用 JSP
jsp? 好多年没用了。重新整一下 还费了点时间,记录一下。 项目结构: pom: <?xml version"1.0" encoding"UTF-8"?> <project xmlns"http://maven.apache.org/POM/4.0.0" xmlns:xsi"http://ww…...

Vue ③-生命周期 || 脚手架
生命周期 思考:什么时候可以发送初始化渲染请求?(越早越好) 什么时候可以开始操作dom?(至少dom得渲染出来) Vue生命周期: 一个Vue实例从 创建 到 销毁 的整个过程。 生命周期四个…...