抽象工厂设计模式是一种创建型设计模式,它允许你创建一组相关或依赖对象的家族,而无需指定其具体类。这种模式通过提供一个抽象工厂接口来创建一系列相关的产品,每个产品对应一个具体工厂,以此来保证产品的一致性。
结构
抽象工厂设计模式通常由以下角色组成:
- 抽象工厂(Abstract Factory): 定义了创建一组相关产品的抽象方法。通常每个抽象方法对应一个产品类,用于创建该类的实例。
- 具体工厂(Concrete Factory): 实现了抽象工厂接口,负责创建一组相关的具体产品。每个具体工厂对应一个产品族,它负责创建该产品族的所有产品。
- 抽象产品(Abstract Product): 定义了产品的抽象接口。每个具体产品必须实现这个接口。
- 具体产品(Concrete Product): 实现了抽象产品接口,是某个具体工厂创建的对象。
工作流程
- 创建抽象工厂接口:首先,你需要创建一个抽象工厂接口,该接口声明了用于创建产品的抽象方法。
- 创建抽象产品接口:定义一个抽象产品接口,该接口声明了产品的通用操作。
- 实现具体产品:为每个产品族创建具体产品类,实现抽象产品接口,提供产品的具体实现。
- 实现具体工厂:创建具体工厂类,实现抽象工厂接口,负责创建该产品族的具体产品。
- 客户端使用:客户端代码通过抽象工厂接口访问产品,而不直接依赖具体产品类。这样客户端可以使用不同的具体工厂来创建不同的产品族,实现了产品族的替换和扩展。
智能家居项目
设备工厂:bathroomLight.c buzzer.c fire.c livingroomLight.c restaurantLight.c upstairLight.c
指令工厂:socketContrl.c voiceContrl.c
设备工厂
#include <wiringPi.h>
#include <stdlib.h>
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 "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;
}
};
#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;
}
};
#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;
}
};
#include "contrlDevices.h"
#include <stdlib.h>
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;
}
};
#include "contrlDevices.h"
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;
}
}
#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;
}
};
指令工厂
#include <wiringPi.h>
#include <stdlib.h>
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);
#include <wiringPi.h>
#include <stdio.h>
#include <wiringSerial.h>
#include <unistd.h>
#include <stdlib.h>
#include <sys/types.h>
#include <sys/socket.h>
#include <netinet/in.h>
#include <string.h>
#include <arpa/inet.h>
#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:%d\n", n_read);
}
else
{
printf("client quit\n");
}
return n_read;
}
struct InputCommander socketContrl = {
.commandName = "socketServer",
.command = {'\0'},
.port = "8088",
.ipAddress = "192.168.43.136",
.Init = socketInit,
.getCommand = socketGetCommand,
.log = {'\0'},
.next = NULL};
struct InputCommander *addSocketContrlToInputCommandLink(struct InputCommander *phead)
{
if (phead == NULL)
{
return &socketContrl;
}
else
{
socketContrl.next = phead;
phead = &socketContrl;
return phead;
}
};
#include <wiringPi.h>
#include <stdio.h>
#include <wiringSerial.h>
#include <unistd.h>
#include <stdlib.h>
#include "InputCommand.h"
#include <string.h>
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, '\0', sizeof(voicer->command));
nread = read(voicer->fd, voicer->command, sizeof(voicer->command));
return nread;
}
struct InputCommander voiceContrl = {
.commandName = "voice",
.deviceName = "/dev/ttyAMA0",
.command = {'\0'},
.Init = voiceInit,
.getCommand = voiceGetCommand,
.log = {'\0'},
.next = NULL};
struct InputCommander *addVoiceContrlToInputCommandLink(struct InputCommander *phead)
{
if (phead == NULL)
{
return &voiceContrl;
}
else
{
voiceContrl.next = phead;
phead = &voiceContrl;
return phead;
}
};
主函数
#include <stdio.h>
#include <string.h>
#include <stdlib.h>
#include "contrlDevices.h"
#include "InputCommand.h"
#include <unistd.h>
#include <pthread.h>
#include <sys/types.h>
#include <sys/socket.h>
#include <netinet/in.h>
#include <arpa/inet.h>
struct Devices *pdeviceHead = NULL;
struct InputCommander *pCommandHead = NULL;
struct InputCommander *socketHandler = NULL;
int c_fd;
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;
int nread;
voiceHandler = findCommandByName("voice", pCommandHead);
if (voiceHandler == NULL)
{
printf("find voiceHandler error\n");
pthread_exit(NULL);
}
else
{
if (voiceHandler->Init(voiceHandler, NULL, NULL) < 0)
{
printf("voice init error\n");
pthread_exit(NULL);
}
else
{
printf("%s init success\n", voiceHandler->commandName);
}
while (1)
{
nread = voiceHandler->getCommand(voiceHandler);
if (nread == 0)
{
printf("no data from voice\n");
}
else
{
printf("do device contrl:%s\n", voiceHandler->command);
if (strcmp("kysd", voiceHandler->command) == 0)
{
pdeviceHead = findDeviceByName("bathroomLight", pdeviceHead);
pdeviceHead->open(pdeviceHead->pinNum);
printf("已打开浴室灯\n");
}
if (strcmp("gysd", voiceHandler->command) == 0)
{
pdeviceHead = findDeviceByName("bathroomLight", pdeviceHead);
pdeviceHead->close(pdeviceHead->pinNum);
printf("已关闭浴室灯\n");
}
if (strcmp("keld", voiceHandler->command) == 0)
{
pdeviceHead = findDeviceByName("upstairLight", pdeviceHead);
pdeviceHead->open(pdeviceHead->pinNum);
}
if (strcmp("geld", voiceHandler->command) == 0)
{
pdeviceHead = findDeviceByName("upstairLight", pdeviceHead);
pdeviceHead->close(pdeviceHead->pinNum);
}
if (strcmp("kktd", voiceHandler->command) == 0)
{
pdeviceHead = findDeviceByName("livingroomLight", pdeviceHead);
pdeviceHead->open(pdeviceHead->pinNum);
}
if (strcmp("gktd", voiceHandler->command) == 0)
{
pdeviceHead = findDeviceByName("livingroomLight", pdeviceHead);
pdeviceHead->close(pdeviceHead->pinNum);
}
if (strcmp("kctd", voiceHandler->command) == 0)
{
pdeviceHead = findDeviceByName("restaurantLight", pdeviceHead);
pdeviceHead->open(pdeviceHead->pinNum);
}
if (strcmp("gctd", voiceHandler->command) == 0)
{
pdeviceHead = findDeviceByName("restaurantLight", pdeviceHead);
pdeviceHead->close(pdeviceHead->pinNum);
}
if (strcmp("ksyd", voiceHandler->command) == 0)
{
pdeviceHead = findDeviceByName("bathroomLight", pdeviceHead);
pdeviceHead->open(pdeviceHead->pinNum);
pdeviceHead = findDeviceByName("upstairLight", pdeviceHead);
pdeviceHead->open(pdeviceHead->pinNum);
pdeviceHead = findDeviceByName("livingroomLight", pdeviceHead);
pdeviceHead->open(pdeviceHead->pinNum);
pdeviceHead = findDeviceByName("restaurantLight", pdeviceHead);
pdeviceHead->open(pdeviceHead->pinNum);
}
if (strcmp("gsyd", voiceHandler->command) == 0)
{
pdeviceHead = findDeviceByName("bathroomLight", pdeviceHead);
pdeviceHead->close(pdeviceHead->pinNum);
pdeviceHead = findDeviceByName("upstairLight", pdeviceHead);
pdeviceHead->close(pdeviceHead->pinNum);
pdeviceHead = findDeviceByName("livingroomLight", pdeviceHead);
pdeviceHead->close(pdeviceHead->pinNum);
pdeviceHead = findDeviceByName("restaurantLight", pdeviceHead);
pdeviceHead->close(pdeviceHead->pinNum);
}
}
}
}
}
void *read_thread(void *datas)
{
int n_read;
while (1)
{
memset(socketHandler->command, '\0', 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 command\n ");
}
else
{
printf("Get socketCommand:%s\n", socketHandler->command);
if (strcmp("kysd", socketHandler->command) == 0)
{
pdeviceHead = findDeviceByName("bathroomLight", pdeviceHead);
pdeviceHead->open(pdeviceHead->pinNum);
printf("已打开浴室灯\n");
}
if (strcmp("gysd", socketHandler->command) == 0)
{
pdeviceHead = findDeviceByName("bathroomLight", pdeviceHead);
pdeviceHead->close(pdeviceHead->pinNum);
printf("已关闭浴室灯\n");
}
if (strcmp("keld", socketHandler->command) == 0)
{
pdeviceHead = findDeviceByName("upstairLight", pdeviceHead);
pdeviceHead->open(pdeviceHead->pinNum);
}
if (strcmp("geld", socketHandler->command) == 0)
{
pdeviceHead = findDeviceByName("upstairLight", pdeviceHead);
pdeviceHead->close(pdeviceHead->pinNum);
}
if (strcmp("kktd", socketHandler->command) == 0)
{
pdeviceHead = findDeviceByName("livingroomLight", pdeviceHead);
pdeviceHead->open(pdeviceHead->pinNum);
}
if (strcmp("gktd", socketHandler->command) == 0)
{
pdeviceHead = findDeviceByName("livingroomLight", pdeviceHead);
pdeviceHead->close(pdeviceHead->pinNum);
}
if (strcmp("kctd", socketHandler->command) == 0)
{
pdeviceHead = findDeviceByName("restaurantLight", pdeviceHead);
pdeviceHead->open(pdeviceHead->pinNum);
}
if (strcmp("gctd", socketHandler->command) == 0)
{
pdeviceHead = findDeviceByName("restaurantLight", pdeviceHead);
pdeviceHead->close(pdeviceHead->pinNum);
}
if (strcmp("ksyd", socketHandler->command) == 0)
{
pdeviceHead = findDeviceByName("bathroomLight", pdeviceHead);
pdeviceHead->open(pdeviceHead->pinNum);
pdeviceHead = findDeviceByName("upstairLight", pdeviceHead);
pdeviceHead->open(pdeviceHead->pinNum);
pdeviceHead = findDeviceByName("livingroomLight", pdeviceHead);
pdeviceHead->open(pdeviceHead->pinNum);
pdeviceHead = findDeviceByName("restaurantLight", pdeviceHead);
pdeviceHead->open(pdeviceHead->pinNum);
}
if (strcmp("gsyd", socketHandler->command) == 0)
{
pdeviceHead = findDeviceByName("bathroomLight", pdeviceHead);
pdeviceHead->close(pdeviceHead->pinNum);
pdeviceHead = findDeviceByName("upstairLight", pdeviceHead);
pdeviceHead->close(pdeviceHead->pinNum);
pdeviceHead = findDeviceByName("livingroomLight", pdeviceHead);
pdeviceHead->close(pdeviceHead->pinNum);
pdeviceHead = findDeviceByName("restaurantLight", pdeviceHead);
pdeviceHead->close(pdeviceHead->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 error\n");
pthread_exit(NULL);
}
else
{
printf("%s init success\n", 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 *fire_thread(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()
{
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);
pthread_create(&socketThread, NULL, socket_thread, NULL);
// 3.4火灾线程
pthread_create(&fireThread, NULL, fire_thread, NULL);
pthread_join(voiceThread, NULL);
pthread_join(socketThread, NULL);
pthread_join(fireThread, NULL);
return 0;
}
标签:struct,int,pinNum,智能家居,phead,pdeviceHead,NULL
From: https://www.cnblogs.com/keep--fighting/p/17741057.html