什么是设计模式
-
设计模式(Design pattern)代表了最佳的实践,通常被有经验的面向对象的软件开发人员所采用。设计模式是软件开发人员在软件开发过程中面临的一般问题的解决方案。这些解决方案是众多软件开发人员经过相当长的一段时间的试验和错误总结出来的。
-
设计模式是一套被反复使用的、多数人知晓的、经过分类编目的、代码设计经验的总结。
-
使用设计模式是为了重用代码、让代码更容易被他人理解、保证代码可靠性。
-
算法不是设计模式,因为算法致力于解决问题非设计问题
-
设计模式通常描述了一组相互紧密作用的类与对象。
类和对象
- 类:类是面向对象程序设计实现信息封装的基础。类是一种用户定义的引用数据类型(结构体),也称类类型。每个类包含数据说明和一组操作数据或传递消息的函数。
- 对象:类的实例称为对象
工厂模式
-
工厂模式(Factory Pattern)是 最常用的设计模式之一。
-
这种类型的设计模式属于创建型模式,它提供了一种创建对象的最佳方式。
-
在工厂模式中,我们在创建对象时不会对客户端暴露创建逻辑(也就是不会在main文件中写对象的创建),并且是通过使用一个共同的接口来指向新创建的对象。
工厂模式的实现案例
注意:
- 在工厂模式中,对象的定义都单独定义一个文件,需要创建一个链表来管理所有对象,在main函数中会初始化链表,通过头插法的形式将所有对象链起来,若要查询某个属性则涉及遍历链表的某个属性知识
- 在main函数中,需要用到的对象才需要初始化,初始化后对象就会添加到链表中,所以头插法的函数要写在每个对象中
- 对象的成员包含函数指针时,函数需要提前定义好,否则会报函数未定义的错误
- 对象的定义要注意结尾有分号,这和结构体的定义不一样,不容易察觉此类错误
- 多个.c文件可以一起编译的前提是只有一个main函数
student.h
#include <stdio.h>
struct Student {
char name[128];
int age;
char sex[128];
void (*favoriteSubject)();//函数指针
struct Student *next;//成员包含结构体指针,用于指向下一个结构体
};
struct Student * putTomInLink(struct Student *phead);
struct Student * putBobInLink(struct Student *phead);
Tom.c
#include "student.h"
void hisFavoriteSubject(){
printf("my favorite_subject is Math\n");
}
struct Student tom = {
.name="Tom",
.age=18,
.sex="boy",
.favoriteSubject=hisFavoriteSubject
};
//如果头指针指向空地址,则头指针指向cat结构体
//如果头指针不是空地址,则将cat指向**头指针原本指向的对象**,头指针指向cat
struct Student * putTomInLink(struct Student *phead){
if(phead == NULL){
phead = &tom;
return phead;
}else{
tom.next=phead;
phead = &tom;
return phead;
}
};
Bob.c
#include "student.h"
void herFavoriteSubject(){
printf("my favorite_subject is English\n");
}
struct Student bob={
.name="Bob",
.age=23,
.sex="girl",
.favoriteSubject=herFavoriteSubject
};
struct Student * putBobInLink(struct Student *phead){
if(phead == NULL){
phead = &bob;
return phead;
}else{
bob.next=phead;
phead = &bob;
return phead;
}
};
mian.c
#include "student.h"
#include <stdio.h>
#include <string.h>
struct Student * findMessageByName(char *name ,struct Student *phead){
struct Student *tmp =phead;
if(tmp == NULL){
printf("the tmp is NULL,please check the tmp\n");
return NULL;
}else{
//循环判断,先循环每个结构体,判断结构体是否满足,不满足继续循环直到找到则返回,循环没结果返回NULL
while(tmp != NULL){
if(strcmp(tmp->name,name)==0){
return tmp;
}
tmp= tmp->next;
}
return NULL;
}
}
int main(){
char name[128];
struct Student *phead =NULL;
struct Student *tmp;
phead = putTomInLink(phead);
phead = putBobInLink(phead);//此时的参数phead是putTomInLink返回的phead,该函数返回值就是最终链表的头,类似于句柄
while(1){
printf("please input Tom or Bob to find the message!\n");
scanf("%s",name);
tmp=findMessageByName(name,phead);
if(tmp != NULL){
tmp->favoriteSubject();
}
}
return 0;
}