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

软件设计模式——工厂模式

软件设计模式——工厂模式

文章目录

  • 软件设计模式——工厂模式
    • 一、设计模式的认知
      • 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就是一个工厂是一个类People1People2作为对象以链表的形式存在在工厂中
    main函数需要做的就是将工厂中的模块组装起来,然后想用哪个就去找到哪个就可以。
    从上面的代码结构不难看出,使用工厂模式使得代码更稳定且拓展性更强,如果需要一个新的模块,只需要再创建一个如People3,并将其插入结构体People中就可以,十分的方便且不会影响到其他的模块

相关文章:

软件设计模式——工厂模式

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

Apache Druid命令执行(CVE-2021-25646)

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

新的 MathWorks 硬件支持包支持从 MATLAB 和 Simulink 模型到高通 Hexagon 神经处理单元架构的自动化代码生成

MathWorks 今天宣布&#xff0c;推出针对 Qualcomm Hexagon™ 神经处理单元&#xff08;NPU&#xff09;的硬件支持包。该处理单元嵌入在 Snapdragon 系列处理器中。MathWorks 硬件支持包&#xff0c;则专门针对 Qualcomm Technologies 的 Hexagon NPU 架构进行优化&#xff0c…...

gorm.io/sharding:改造,当查询条件中不包含分表键时,从自定义方法中获取对应的表进行查询

项目背景 这篇文章是一种特殊的情形——当查询条件中不包含分表键时&#xff0c;从自定义方法中获取对应的表进行查询。实际项目中并不建议这种用法。 当然&#xff0c;这里只是提供一种思路。这篇文章也是这个系列中的第三篇文章。前两篇文章《基于gorm.io/sharding分表中间…...

【CSS】变量的声明与使用

原生变量root 伪类 原生变量 CSS中我们可以统一设置变量方便页面维护。变量声明的时候&#xff0c;自定义样式变量名之前加上两根连词线 " – " 即可&#xff0c;使用 var() 来引用。声明的变量是有作用域的 ( 比如是在html中声明的变量&#xff0c;那么该变量在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]上连续&#xff0c;则 f ( x ) f(x) f(x)在闭区间 [ a , b ] [a,b] [a,b]上有界。 【证】用反证法&#xff0c;假设 f ( x ) f(x) f(x)在 [ …...

Mybatis中sql数组为空判断

一、Mybatis xml中的sql通过if语句判定是否为空 <if test"arrays ! null"> </if>上述示例只能判断arrays数组不为null&#xff0c;那如果是个空数组呢 二、Mybatis xml中的sql通过if语句判定数组非空数组 <if test"arrays ! null and arrays.l…...

12.第二阶段x86游戏实战2-CE找基地址

免责声明&#xff1a;内容仅供学习参考&#xff0c;请合法利用知识&#xff0c;禁止进行违法犯罪活动&#xff01; 本次游戏没法给 内容参考于&#xff1a;微尘网络安全 本人写的内容纯属胡编乱造&#xff0c;全都是合成造假&#xff0c;仅仅只是为了娱乐&#xff0c;请不要…...

笔记整理—内核!启动!—linux应用编程、网络编程部分(3)文件共享与标准IO

文件共享是指同一个文件被多个独立的读写进行操作。同一个文件为同一个inode&#xff0c;同一个pathname也就是同一个静态文件。同时进行操作&#xff0c;打开一个文件未关闭又被另一个操作打开。文件共享的方式可以实现高效的大文件读写。 文件共享的三种方式&#xff1a;①同…...

plt常用函数介绍一

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

基于ExtendSim的 电子制造 仿真模型

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

BGP 路由反射器

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

CSRF高级防御绕过

1&#xff09;回顾low级别做过csrf页面的密码重置&#xff0c;重复之前的操作&#xff0c;我们发现级别调整中级之后&#xff0c;报错如下 2&#xff09;检查源码 进入dvwa源码&#xff0c;查找到checktoken&#xff1a; 3&#xff09;在dvwa-csrf页面上&#xff0c;抓包 http…...

MySQL安装文档-Windows

文章目录 MySQL安装1. 安装2. 配置 MySQL安装 1. 安装 1). 双击官方下来的安装包文件 2). 根据安装提示进行安装 安装MySQL的相关组件&#xff0c;这个过程可能需要耗时几分钟&#xff0c;耐心等待。 输入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!再见前端!

各位朋友大家晚上好&#xff0c;夜深了&#xff0c;睡不着&#xff0c;想想还是写一篇文章和大家说再见吧&#xff01; 自2014年入行前端以来&#xff0c;满打满算差不多整整十年了&#xff0c;这十年可以说是见证了中国整个互联网的起飞到全盛时期。这期间经历了电商、金融、…...

【源码+文档+调试讲解】人事管理系统设计与实现Python

摘 要 人事管理系统的目的是让使用者可以更方便的将人、设备和场景更立体的连接在一起。能让用户以更科幻的方式使用产品&#xff0c;体验高科技时代带给人们的方便&#xff0c;同时也能让用户体会到与以往常规产品不同的体验风格。 与安卓&#xff0c;iOS相比较起来&#xff…...

基于注意力机制的图表示学习:GRAPH-BERT模型

人工智能咨询培训老师叶梓 转载标明出处 图神经网络&#xff08;GNNs&#xff09;在处理图结构数据方面取得了显著的进展&#xff0c;但现有模型在深层结构中存在性能问题&#xff0c;如“悬挂动画问题”和“过平滑问题”。而且图数据内在的相互连接特性限制了大规模图输入的并…...

linux服务器安装原生的php环境

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

数电学习基础(逻辑门电路+)

1.逻辑门电路 1.1逻辑门电路的简介 1.1.1各种逻辑门电路的简介 基本概念 &#xff08;1&#xff09;实现基本逻辑运算和常用逻辑运算的电路称为逻辑门电路&#xff0c;简称门电路。逻辑门电路是组成各种数字电路的基本单元电路。将构成门电路的元器件制作一块半导体芯片上再…...

Lombok 的 @Data 注解失效,未生成 getter/setter 方法引发的HTTP 406 错误

HTTP 状态码 406 (Not Acceptable) 和 500 (Internal Server Error) 是两类完全不同的错误&#xff0c;它们的含义、原因和解决方法都有显著区别。以下是详细对比&#xff1a; 1. HTTP 406 (Not Acceptable) 含义&#xff1a; 客户端请求的内容类型与服务器支持的内容类型不匹…...

黑马Mybatis

Mybatis 表现层&#xff1a;页面展示 业务层&#xff1a;逻辑处理 持久层&#xff1a;持久数据化保存 在这里插入图片描述 Mybatis快速入门 ![在这里插入图片描述](https://i-blog.csdnimg.cn/direct/6501c2109c4442118ceb6014725e48e4.png //logback.xml <?xml ver…...

镜像里切换为普通用户

如果你登录远程虚拟机默认就是 root 用户&#xff0c;但你不希望用 root 权限运行 ns-3&#xff08;这是对的&#xff0c;ns3 工具会拒绝 root&#xff09;&#xff0c;你可以按以下方法创建一个 非 root 用户账号 并切换到它运行 ns-3。 一次性解决方案&#xff1a;创建非 roo…...

WEB3全栈开发——面试专业技能点P2智能合约开发(Solidity)

一、Solidity合约开发 下面是 Solidity 合约开发 的概念、代码示例及讲解&#xff0c;适合用作学习或写简历项目背景说明。 &#x1f9e0; 一、概念简介&#xff1a;Solidity 合约开发 Solidity 是一种专门为 以太坊&#xff08;Ethereum&#xff09;平台编写智能合约的高级编…...

安卓基础(aar)

重新设置java21的环境&#xff0c;临时设置 $env:JAVA_HOME "D:\Android Studio\jbr" 查看当前环境变量 JAVA_HOME 的值 echo $env:JAVA_HOME 构建ARR文件 ./gradlew :private-lib:assembleRelease 目录是这样的&#xff1a; MyApp/ ├── app/ …...

云原生玩法三问:构建自定义开发环境

云原生玩法三问&#xff1a;构建自定义开发环境 引言 临时运维一个古董项目&#xff0c;无文档&#xff0c;无环境&#xff0c;无交接人&#xff0c;俗称三无。 运行设备的环境老&#xff0c;本地环境版本高&#xff0c;ssh不过去。正好最近对 腾讯出品的云原生 cnb 感兴趣&…...

tomcat入门

1 tomcat 是什么 apache开发的web服务器可以为java web程序提供运行环境tomcat是一款高效&#xff0c;稳定&#xff0c;易于使用的web服务器tomcathttp服务器Servlet服务器 2 tomcat 目录介绍 -bin #存放tomcat的脚本 -conf #存放tomcat的配置文件 ---catalina.policy #to…...

VisualXML全新升级 | 新增数据库编辑功能

VisualXML是一个功能强大的网络总线设计工具&#xff0c;专注于简化汽车电子系统中复杂的网络数据设计操作。它支持多种主流总线网络格式的数据编辑&#xff08;如DBC、LDF、ARXML、HEX等&#xff09;&#xff0c;并能够基于Excel表格的方式生成和转换多种数据库文件。由此&…...

jdbc查询mysql数据库时,出现id顺序错误的情况

我在repository中的查询语句如下所示&#xff0c;即传入一个List<intager>的数据&#xff0c;返回这些id的问题列表。但是由于数据库查询时ID列表的顺序与预期不一致&#xff0c;会导致返回的id是从小到大排列的&#xff0c;但我不希望这样。 Query("SELECT NEW com…...

java高级——高阶函数、如何定义一个函数式接口类似stream流的filter

java高级——高阶函数、stream流 前情提要文章介绍一、函数伊始1.1 合格的函数1.2 有形的函数2. 函数对象2.1 函数对象——行为参数化2.2 函数对象——延迟执行 二、 函数编程语法1. 函数对象表现形式1.1 Lambda表达式1.2 方法引用&#xff08;Math::max&#xff09; 2 函数接口…...