工厂模式(Factory Pattern)是 Java 中最常用的设计模式之一。这种类型的设计模式属于创建型模式,它提供了一种创建对象的最佳方式。
在工厂模式中,我们在创建对象时不会对客户端暴露创建逻辑,并且是通过使用一个共同的接口来指向新创建的对象。
这是工厂模式的定义,我们自然就不必多说了,主要想写一下使用工厂模式具备了哪些优势。
使用工厂模式的好处 1.解耦通过工厂模式可以把对象的创建和使用过程分割开来。比如说 Class A 想调用 Class B的方法,那么我们无需关心B是如何创建的,直接去工厂获取就行。
2. 减少代码量,易于维护如果我们直接new一个对象时,如果需要的对象构造方法比较复杂,那么可能需要一连串的代码去创建对象,如果在别的类中又需要创建该对象,那么代码的重复度肯定不小。通过工厂模式的话,我们把对象创建的具体逻辑给隐藏起来了,交给工厂统一管理,这样不仅减少了代码量,以后如果想改代码的话,只需要改一处即可,也方便我们日常的维护。
本文用工厂模式来实现,话不多说,直接上代码。 设备工厂 contrlDevices.h#include指令工厂 InputCommand.h#include struct Devices { char deviceName[128]; int status; int pinNum; int (*open)(int pinNum); int (*close)(int pinNum); int (*deviceInit)(int pinNum); int (*readStatus)(int pinNum); int (*changeStatus)(int status); struct Devices *next; }; struct Devices* addBathroomLightToDevicelink(struct Devices *phead); struct Devices* addUpstairLightToDevicelink(struct Devices *phead); struct Devices* addLivingroomLightToDevicelink(struct Devices *phead); struct Devices* addRestaurantLightToDevicelink(struct Devices *phead); struct Devices* addFireToDevicelink(struct Devices *phead); struct Devices* addBuzzerToDevicelink(struct Devices *phead);
#include灯光控制 客厅灯#include struct InputCommander { char commandName[128]; char deviceName[128]; char command[32]; int (*Init)(struct InputCommander *voicer,char *ipAddress,char *port); int (*getCommand)(struct InputCommander* voicer); char log[1024]; int fd; char port[12]; char ipAddress[32]; int sfd; struct InputCommander *next; }; struct InputCommander* addVoiceContrlToInputCommandlink(struct InputCommander *phead); struct InputCommander* addSocketContrlToInputCommandlink(struct InputCommander *phead);
livingroomLight.c
#include "contrlDevices.h"
int livingroomLightOpen(int pinNum)
{
digitalWrite(pinNum,LOW);
}
int livingroomLightClose(int pinNum)
{
digitalWrite(pinNum,HIGH);
}
int livingroomLightCloseInit(int pinNum)
{
pinMode(pinNum,OUTPUT);
digitalWrite(pinNum,HIGH);
}
int livingroomLightStatus(int status)
{
}
struct Devices livingroomLight = {
.deviceName = "livingroomLight",
.pinNum = 28,
.open = livingroomLightOpen,
.close = livingroomLightClose,
.deviceInit = livingroomLightCloseInit,
.changeStatus = livingroomLightStatus
};
struct Devices* addLivingroomLightToDevicelink(struct Devices *phead)
{
if(phead ==NULL){
return &livingroomLight;
}else{
livingroomLight.next = phead;
phead = &livingroomLight;
return phead;
}
};
餐厅灯
restaurantLight.c
#include "contrlDevices.h"
int restaurantLightOpen(int pinNum)
{
digitalWrite(pinNum,LOW);
}
int restaurantLightClose(int pinNum)
{
digitalWrite(pinNum,HIGH);
}
int restaurantLightCloseInit(int pinNum)
{
pinMode(pinNum,OUTPUT);
digitalWrite(pinNum,HIGH);
}
int restaurantLightStatus(int status)
{
}
struct Devices restaurantLight = {
.deviceName = "restaurantLight",
.pinNum = 29,
.open = restaurantLightOpen,
.close = restaurantLightClose,
.deviceInit = restaurantLightCloseInit,
.changeStatus = restaurantLightStatus
};
struct Devices* addRestaurantLightToDevicelink(struct Devices *phead)
{
if(phead ==NULL){
return &restaurantLight;
}else{
restaurantLight.next = phead;
phead = &restaurantLight;
return phead;
}
};
二楼灯
upstairLight.c
#include "contrlDevices.h" #include浴室灯int upstairLightOpen(int pinNum) { digitalWrite(pinNum,LOW); } int upstairLightClose(int pinNum) { digitalWrite(pinNum,HIGH); } int upstairLightCloseInit(int pinNum) { pinMode(pinNum,OUTPUT); digitalWrite(pinNum,HIGH); } int upstairLightStatus(int status) { } struct Devices upstairLight = { .deviceName = "upstairLight", .pinNum = 27, .open = upstairLightOpen, .close = upstairLightClose, .deviceInit = upstairLightCloseInit, .changeStatus = upstairLightStatus }; struct Devices* addUpstairLightToDevicelink(struct Devices *phead) { if(phead ==NULL){ return &upstairLight; }else{ upstairLight.next = phead; phead = &upstairLight; return phead; } };
bathroomLight.c
#include "contrlDevices.h"
int bathroomLightOpen(int pinNum)
{
digitalWrite(pinNum,LOW);
}
int bathroomLightClose(int pinNum)
{
digitalWrite(pinNum,HIGH);
}
int bathroomLightCloseInit(int pinNum)
{
pinMode(pinNum,OUTPUT);
digitalWrite(pinNum,HIGH);
}
int bathroomLightStatus(int status)
{
}
struct Devices bathroomLight = {
.deviceName = "bathroomLight",
.pinNum = 26,
.open = bathroomLightOpen,
.close = bathroomLightClose,
.deviceInit = bathroomLightCloseInit,
.changeStatus = bathroomLightStatus
};
struct Devices* addBathroomLightToDevicelink(struct Devices *phead)
{
if(phead ==NULL){
return &bathroomLight;
}else{
bathroomLight.next = phead;
phead = &bathroomLight;
return phead;
}
};
蜂鸣器
buzzer.c
#include "contrlDevices.h"
int buzzerInit(int pinNum); //一些函数声明
int buzzerOpen(int pinNum);
int buzzerClose(int pinNum);
struct Devices *addBuzzerToDevicelink(struct Devices *phead);
struct Devices buzzer = { //“蜂鸣器”设备链表节点
.deviceName = "buzzer",
.pinNum = 22, //树莓派gpio引脚29
.deviceInit = buzzerInit,
.open = buzzerOpen,
.close = buzzerClose,
};
int buzzerInit(int pinNum) //初始化函数
{
pinMode(pinNum,OUTPUT); //配置引脚为输出引脚
digitalWrite(pinNum,HIGH); //引脚输出高电平,即默认为关闭状态
}
int buzzerOpen(int pinNum) //打开函数
{
digitalWrite(pinNum,LOW);
}
int buzzerClose(int pinNum) //关闭函数
{
digitalWrite(pinNum,HIGH);
}
struct Devices *addBuzzerToDevicelink(struct Devices *phead) //头插法将设备节点加入设备工厂链表函数
{
if(phead == NULL){
return &buzzer;
}else{
buzzer.next = phead;
phead = &buzzer;
return phead;
}
}
火焰检测
fire.c
#include "contrlDevices.h"
int fireIfOrNotInit(int pinNum)
{
pinMode(pinNum,INPUT);
digitalWrite(pinNum,HIGH);
}
int fireStatusRead(int pinNum)
{
return digitalRead(pinNum);
}
struct Devices fireIfOrNot = {
.deviceName = "fireIfOrNot",
.pinNum = 21,
.deviceInit = fireIfOrNotInit,
.readStatus = fireStatusRead
};
struct Devices* addFireToDevicelink(struct Devices *phead)
{
if(phead ==NULL){
return &fireIfOrNot;
}else{
fireIfOrNot.next = phead;
phead = &fireIfOrNot;
return phead;
}
};
网络socket
socketContrl.c
#include语音模块#include #include #include #include #include #include #include #include #include #include "InputCommand.h" int socketInit(struct InputCommander *socketMes,char *ipAddress,char *port) { int s_fd; struct sockaddr_in s_addr; memset(&s_addr,0,sizeof(struct sockaddr_in)); //1 .socket s_fd = socket(AF_INET,SOCK_STREAM,0); if(s_fd == -1){ perror("socket"); exit(-1); } s_addr.sin_family = AF_INET; s_addr.sin_port = htons(atoi(socketMes->port)); inet_aton(socketMes->ipAddress,&s_addr.sin_addr); //2.bind bind(s_fd,(struct sockaddr *)&s_addr,sizeof(struct sockaddr_in)); //3.listen listen(s_fd,10); printf("socket Server listening......n"); socketMes->sfd = s_fd; return s_fd; } int socketGetCommand(struct InputCommander* socketMes) { int c_fd; int n_read = 0; struct sockaddr_in c_addr; int clen = sizeof(struct sockaddr_in); memset(&c_addr,0,sizeof(struct sockaddr_in)); c_fd = accept(socketMes->sfd,(struct sockaddr *)&c_addr,&clen); n_read = read(c_fd,socketMes->command,sizeof(socketMes->command)); if(n_read == -1){ perror("read"); }else if(n_read>0){ printf("nget:%dn",n_read); }else{ printf("client quitn"); } return n_read; } struct InputCommander socketContrl = { .commandName = "socketServer", .command = {' '}, .port = "8088", .ipAddress = "192.168.43.136", .Init = socketInit, .getCommand = socketGetCommand, .log = {' '}, .next = NULL }; struct InputCommander* addSocketContrlToInputCommandlink(struct InputCommander *phead) { if(phead == NULL){ return &socketContrl; }else{ socketContrl.next = phead; phead = &socketContrl; return phead; } };
voiceContrl.c
#include主函数#include #include #include #include #include "InputCommand.h" #include int voiceInit(struct InputCommander *voicer,char *ipAddress,char *port) { int fd; if((fd = serialOpen(voicer->deviceName,9600))==-1) exit(-1); voicer->fd = fd; return fd; } int voiceGetCommand(struct InputCommander* voicer) { int nread = 0; memset(voicer->command,' ',sizeof(voicer->command)); nread = read(voicer->fd,voicer->command,sizeof(voicer->command)); return nread; } struct InputCommander voiceContrl = { .commandName = "voice", .deviceName = "/dev/ttyAMA0", .command = {' '}, .Init = voiceInit, .getCommand = voiceGetCommand, .log = {' '}, .next = NULL }; struct InputCommander* addVoiceContrlToInputCommandlink(struct InputCommander *phead) { if(phead == NULL){ return &voiceContrl; }else{ voiceContrl.next = phead; phead = &voiceContrl; return phead; } };
mainPro.c
#include#include #include #include "contrlDevices.h" #include "InputCommand.h" #include #include #include #include #include #include struct Devices *pdeviceHead = NULL; struct InputCommander *pCommandHead = NULL; struct InputCommander* socketHandler = NULL; int c_fd; // struct Devices* pdeviceHead1 = NULL; struct Devices* pdeviceHead2 = NULL; struct Devices* pdeviceHead3 = NULL; struct Devices* pdeviceHead4 = NULL; // struct Devices* findDeviceByName(char *name,struct Devices *phead) { struct Devices *tmp = phead; if(phead == NULL){ return NULL; }else{ while(tmp!=NULL){ if(strcmp(tmp->deviceName,name)==0){ return tmp; } tmp = tmp->next; } return NULL; } } struct InputCommander* findCommandByName(char *name,struct InputCommander *phead) { struct InputCommander *tmp = phead; if(phead == NULL){ return NULL; }else{ while(tmp!=NULL){ if(strcmp(tmp->commandName,name)==0){ return tmp; } tmp = tmp->next; } return NULL; } } void *voice_thread(void* datas) { struct InputCommander* voiceHandler; struct Devices *linkHandler; int nread; voiceHandler = findCommandByName("voice", pCommandHead); if(voiceHandler==NULL){ printf("find voiceHandler errorn"); pthread_exit(NULL); //return NULL; }else{ if(voiceHandler->Init(voiceHandler,NULL,NULL)<0){ printf("voice init errorn"); pthread_exit(NULL); //return NULL; }else{ printf("%s init successn",voiceHandler->commandName); } while(1){ nread = voiceHandler->getCommand(voiceHandler); if(nread == 0){ printf("no data from voicen"); }else{ printf("do device contrl:%sn",voiceHandler->command); if(strcmp("kysd",voiceHandler->command) == 0){ linkHandler = findDeviceByName("bathroomLight",pdeviceHead); linkHandler->open(linkHandler->pinNum); printf("已打开浴室灯n"); } if(strcmp("gysd",voiceHandler->command) == 0){ linkHandler = findDeviceByName("bathroomLight",pdeviceHead); linkHandler->close(linkHandler->pinNum); printf("已关闭浴室灯n"); } if(strcmp("keld",voiceHandler->command) == 0){ linkHandler = findDeviceByName("upstairLight",pdeviceHead); linkHandler->open(linkHandler->pinNum); } if(strcmp("geld",voiceHandler->command) == 0){ linkHandler = findDeviceByName("upstairLight",pdeviceHead); linkHandler->close(linkHandler->pinNum); } if(strcmp("kktd",voiceHandler->command) == 0){ linkHandler = findDeviceByName("livingroomLight",pdeviceHead); linkHandler->open(linkHandler->pinNum); } if(strcmp("gktd",voiceHandler->command) == 0){ linkHandler = findDeviceByName("livingroomLight",pdeviceHead); linkHandler->close(linkHandler->pinNum); } if(strcmp("kctd",voiceHandler->command) == 0){ linkHandler = findDeviceByName("restaurantLight",pdeviceHead); linkHandler->open(linkHandler->pinNum); } if(strcmp("gctd",voiceHandler->command) == 0){ linkHandler = findDeviceByName("restaurantLight",pdeviceHead); linkHandler->close(linkHandler->pinNum); } if(strcmp("ksyd",voiceHandler->command) == 0){ linkHandler = findDeviceByName("bathroomLight",pdeviceHead); linkHandler->open(linkHandler->pinNum); linkHandler = findDeviceByName("upstairLight",pdeviceHead); linkHandler->open(linkHandler->pinNum); linkHandler = findDeviceByName("livingroomLight",pdeviceHead); linkHandler->open(linkHandler->pinNum); linkHandler = findDeviceByName("restaurantLight",pdeviceHead); linkHandler->open(linkHandler->pinNum); } if(strcmp("gsyd",voiceHandler->command) == 0){ linkHandler = findDeviceByName("bathroomLight",pdeviceHead); linkHandler->close(linkHandler->pinNum); linkHandler = findDeviceByName("upstairLight",pdeviceHead); linkHandler->close(linkHandler->pinNum); linkHandler = findDeviceByName("livingroomLight",pdeviceHead); linkHandler->close(linkHandler->pinNum); linkHandler = findDeviceByName("restaurantLight",pdeviceHead); linkHandler->close(linkHandler->pinNum); } } } }} void *read_thread(void* datas) { int n_read; while(1){ memset(socketHandler->command,' ',sizeof(socketHandler->command)); n_read = read(c_fd,socketHandler->command,sizeof(socketHandler->command)); if(n_read == -1){ perror("read"); }else if(n_read == 0){ printf("nNo receiving commandn "); }else{ printf("Get socketCommand:%sn",socketHandler->command); if(strcmp("kysd",voiceHandler->command) == 0){ linkHandler = findDeviceByName("bathroomLight",pdeviceHead); linkHandler->open(linkHandler->pinNum); printf("已打开浴室灯n"); } if(strcmp("gysd",voiceHandler->command) == 0){ linkHandler = findDeviceByName("bathroomLight",pdeviceHead); linkHandler->close(linkHandler->pinNum); printf("已关闭浴室灯n"); } if(strcmp("keld",voiceHandler->command) == 0){ linkHandler = findDeviceByName("upstairLight",pdeviceHead); linkHandler->open(linkHandler->pinNum); } if(strcmp("geld",voiceHandler->command) == 0){ linkHandler = findDeviceByName("upstairLight",pdeviceHead); linkHandler->close(linkHandler->pinNum); } if(strcmp("kktd",voiceHandler->command) == 0){ linkHandler = findDeviceByName("livingroomLight",pdeviceHead); linkHandler->open(linkHandler->pinNum); } if(strcmp("gktd",voiceHandler->command) == 0){ linkHandler = findDeviceByName("livingroomLight",pdeviceHead); linkHandler->close(linkHandler->pinNum); } if(strcmp("kctd",voiceHandler->command) == 0){ linkHandler = findDeviceByName("restaurantLight",pdeviceHead); linkHandler->open(linkHandler->pinNum); } if(strcmp("gctd",voiceHandler->command) == 0){ linkHandler = findDeviceByName("restaurantLight",pdeviceHead); linkHandler->close(linkHandler->pinNum); } if(strcmp("ksyd",voiceHandler->command) == 0){ linkHandler = findDeviceByName("bathroomLight",pdeviceHead); linkHandler->open(linkHandler->pinNum); linkHandler = findDeviceByName("upstairLight",pdeviceHead); linkHandler->open(linkHandler->pinNum); linkHandler = findDeviceByName("livingroomLight",pdeviceHead); linkHandler->open(linkHandler->pinNum); linkHandler = findDeviceByName("restaurantLight",pdeviceHead); linkHandler->open(linkHandler->pinNum); } if(strcmp("gsyd",voiceHandler->command) == 0){ linkHandler = findDeviceByName("bathroomLight",pdeviceHead); linkHandler->close(linkHandler->pinNum); linkHandler = findDeviceByName("upstairLight",pdeviceHead); linkHandler->close(linkHandler->pinNum); linkHandler = findDeviceByName("livingroomLight",pdeviceHead); linkHandler->close(linkHandler->pinNum); linkHandler = findDeviceByName("restaurantLight",pdeviceHead); linkHandler->close(linkHandler->pinNum); } } } } void *socket_thread(void* datas) { int n_read = 0; pthread_t readThread; struct sockaddr_in c_addr; memset(&c_addr,0,sizeof(struct sockaddr_in)); int clen = sizeof(struct sockaddr_in); socketHandler = findCommandByName("socketServer", pCommandHead); if(socketHandler == NULL){ printf("find socketHandler errorn"); pthread_exit(NULL); }else{ printf("%s init successn",socketHandler->commandName); } socketHandler->Init(socketHandler,NULL,NULL); while(1){ c_fd = accept(socketHandler->sfd,(struct sockaddr*)&c_addr,&clen); pthread_create(&readThread,NULL,read_thread,NULL); //只要有连接,就创建线程去对接。线程共用内存资源,同一时刻,所有设备只有一种状态。也可PV操作 } } void *fireThread(void *data) { int status; struct Devices* firetmp = NULL; struct Devices* buztmp = NULL; firetmp = findDeviceByName("fireIfOrNot",pdeviceHead); //寻找“火焰传感器”链表节点,返回给firetmp buztmp = findDeviceByName("buzzer",pdeviceHead); //寻找“蜂鸣器”链表节点,返回给buztmp while(1){ status = firetmp->readStatus(firetmp->pinNum); //读取“火焰传感器”状态 if(status == 0){ //检测到火焰或强光源 buztmp->open(buztmp->pinNum); //打开蜂鸣器 delay(1000); //延时1000毫秒=1秒 } if(status == 1){ //未检测到火焰、强光源或解除警报 buztmp->close(buztmp->pinNum); //关闭蜂鸣器 } } } int main() { char *name[128]; struct Devices *tmp=NULL; pthread_t voiceThread; pthread_t socketThread; pthread_t fireThread; if(-1==wiringPiSetup()) return -1; //1.指令工厂初始化 pCommandHead = addVoiceContrlToInputCommandlink(pCommandHead); pCommandHead = addSocketContrlToInputCommandlink(pCommandHead); //2.设备控制工厂初始化 pdeviceHead = addBathroomLightToDevicelink(pdeviceHead); pdeviceHead = addUpstairLightToDevicelink(pdeviceHead); pdeviceHead = addLivingroomLightToDevicelink(pdeviceHead); pdeviceHead = addRestaurantLightToDevicelink(pdeviceHead); pdeviceHead = addFireToDevicelink(pdeviceHead); pdeviceHead = addBuzzerToDevicelink(pdeviceHead); struct Devices *tmpequiphead = pdeviceHead; while(tmpequiphead != NULL){ //设备工厂所有设备初始化 tmpequiphead->deviceInit(tmpequiphead->pinNum); tmpequiphead = tmpequiphead->next; } //3.线程池建立 //3.1语音线程 pthread_create(&voiceThread,NULL,voice_thread,NULL); //3.2socket线程 //while(1){ //pthread_create(&socketThread,NULL,socket_thread,NULL); //pthread_join(socketThread,NULL); //} //3.3摄像头线程 //3.4火灾线程 pthread_create(&fireThread,NULL,fire_thread,NULL); pthread_join(voiceThread,NULL); pthread_join(socketThread,NULL); pthread_join(fireThread,NULL); return 0; }



