软件设计模式------工厂模式
文章目录
一、设计模式的认知
1.1 什么是软件设计模式:
软件设计模式 ,又称设计模式 。它是一套被反复使用、多数人知晓的、经过分类编目的、代码设计经验的总结。使用设计模式是为了可重用代码、让代码更容易被他人理解、保证代码可靠性、程序的重用性 。综上:设计模式就是泛指一系列编程的思想,是代码设计经验的总结,基于设计模式来开发代码可以使得程序更加稳定,拓展性更强。
1.2 为什么要学习设计模式:
在以往的项目开发中,不管是 ftp服务器 还是 图像识别智能垃圾桶 又或者更之前的智能小车项目 ,都没有一个固定的代码开发格式,更多的是根据需求一个个实现功能,虽然有了分文件编程的思想,但是代码整体还是缺乏规整度。尤其是在开发过程中,一个功能的实现经常会导致其他功能出现问题,所以需要学习设计模式,使得代码更加健壮和格式化。
1.3 设计模式的分类:
软件设计模式共有23种,总体来说可以被分为三大类:
- 五种创建型模式:工厂方法模式、抽象工厂模式、单例模式、建造者模式、原型模式。
- 七种结构型模式:适配器模式、装饰器模式、代理模式、外观模式、桥接模式、组合模式、享元模式。
- 十一种行为型模式:策略模式、模板方法模式、观察者模式、迭代子模式、责任链模式、命令模式、备忘录模式、状态模式、访问者模式、中介者模式、解释器模式。
下面我们就来学习创建型模式中的一种:工厂模式。
二、工厂模式
- 工厂模式(Factory Pattern)是程序中最常见的设计模式之一 ,这种类型的设计模式属于:创建型模式 ,它提供了一种创建对象的最佳方法。
- 在工厂模式中,我们在创建对象时不会对客户端暴露创建的逻辑,并且是通过使用一个共同的接口来指向一个新创建的对象。
2.1 工厂模式实例:
- .h文件
c
#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文件
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文件
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文件
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
中就可以,十分的方便且不会影响到其他的模块。