设计模式-C版本-工厂模式

C版本

工厂模式的实现步骤如下:

  • 定义一个抽象产品接口,用于定义一组产品的通用行为。
  • 定义一个具体产品类,实现抽象产品接口,用于提供具体的产品实现。
  • 定义一个抽象工厂接口,用于定义工厂类应该实现的方法。
  • 定义一个具体工厂类,实现抽象工厂接口,用于创建具体的产品对象。
  • 在客户端代码中使用工厂类创建具体的产品对象。

示例代码一

Code
/*
1.简单工厂模式:struct写法
https://developer.aliyun.com/article/1171580
*/
typedef enum
{
SUV,
BUS,
CAR,
}CAR_TYPE;
typedef struct
{
int price;
char * type;
}CAR_MODEL;
CAR_MODEL * car_factory(CAR_TYPE type)
{
CAR_MODEL *car = (CAR_MODEL *)malloc(sizeof(CAR_MODEL));
if (car == NULL)
return NULL;
switch (type)
{
case SUV:
car->price = 170000;
car->type = "SUV car";
break;
case BUS:
car->price = 150000;
car->type = "BUS car";
break;
case CAR:
car->price = 120000;
car->type = "CAR car";
break;
default:
printf("Invalid car\n");
free(car);
break;
}
return car;
}
void simple_factory(void)
{
CAR_MODEL * A = car_factory(SUV);
printf("A price:%d, model:%s\r\n", A->price, A->type);
CAR_MODEL * B = car_factory(BUS);
printf("B price:%d, model:%s\r\n", B->price, B->type);
CAR_MODEL * C = car_factory(CAR);
printf("C price:%d, model:%s\r\n", C->price, C->type);
CAR_MODEL * invalid = car_factory(11);
printf("invalid price:%d, model:%s\r\n", invalid->price, invalid->type);
free(A);
free(B);
free(C);
return ;
}

示例代码二

Code
/*
2.简单工厂模式:typedef写法
https://zhuanlan.zhihu.com/p/613368234
*/
// 水果类型枚举定义
typedef enum FruitType
{
Apple = 1,
Banana,
Pear
}FruitType_;
// 通用结构体
typedef struct FRUIT
{
void (* show)(void);
void (* eat)(int);
char *name;
}Fruit_t;
static void show_apple(void)
{
printf("show_apple\r\n");
}
static void eat_apple(int n)
{
printf("eat_apple %d\r\n", n);
}
// 构造函数-apple
Fruit_t * constructor_fruit_apple(void *obj)
{
Fruit_t *m_fruit = (Fruit_t *)malloc(sizeof(Fruit_t));
m_fruit->name = "Apple";
m_fruit->show = show_apple;
m_fruit->eat = eat_apple;
return m_fruit;
};
static void show_banana(void)
{
printf("show_banana\r\n");
}
static void eat_banana(int n)
{
printf("eat_banana %d\r\n", n);
}
Fruit_t * constructor_fruit_banana(void *obj)
{
// Fruit_t m_fruit; // 局部变量不能直接return,需要malloc申请内存
Fruit_t *m_fruit = (Fruit_t *)malloc(sizeof(Fruit_t));
m_fruit->name = "Banana";
m_fruit->show = show_banana;
m_fruit->eat = eat_banana;
return m_fruit;
}
static void show_pear(void)
{
printf("show_pear\r\n");
}
static void eat_pear(int n)
{
printf("eat_pear %d\r\n", n);
}
void constructor_fruit_pear(Fruit_t * m_fruit)
{
m_fruit->name = "Pear";
m_fruit->show = show_pear;
m_fruit->eat = eat_pear;
return ;
}
// 简单工厂
Fruit_t * simple_factory_fruit(enum FruitType type)
{
Fruit_t * m_fruit = (Fruit_t *)malloc(sizeof(Fruit_t));
switch (type)
{
case Apple:
m_fruit = constructor_fruit_apple(NULL);
break;
case Banana:
m_fruit = constructor_fruit_banana(NULL);
break;
case Pear:
constructor_fruit_pear(m_fruit);
break;
default:
printf("error type\n");
break;
}
return m_fruit;
}
void fruit_main_func(void)
{
Fruit_t * A = NULL;
A = simple_factory_fruit(Apple);
A->show();
A->eat(1);
Fruit_t * B = NULL;
B = simple_factory_fruit(Banana);
B->show();
B->eat(1);
Fruit_t * C = NULL;
C = simple_factory_fruit(Pear);
C->show();
C->eat(1);
free(A);
free(B);
free(C);
return ;
}

示例代码三

Code
/*
4.工厂模式:列表方法
https://blog.csdn.net/mirco_mcu/article/details/114684142
*/
void eeprom_init(void)
{
printf("初始化 EEPROM\n");
}
void eeprom_open(void)
{
printf("启用 EEPROM\n");
}
void eeprom_write(int addr, char *data, int len)
{
printf("向EEPROM 地址:%x 写入%d 字节数据:%s\n", addr, len, (char *)data);
}
void flash_init(void)
{
printf("初始化 FLASH\n");
}
void flash_open(void)
{
printf("启用 FLASH\n");
}
void flash_write(int addr, char *data, int len)
{
printf("向FLASH 地址:%x 写入%d 字节数据:%s\n", addr, len, (char *)data);
}
typedef struct STORAGE
{
char *name;
void (* init)(void);
void (* open)(void);
void (* write)(int, char *, int);
}storage_t;
storage_t storage_list[] =
{
{"eeprom", eeprom_init, eeprom_open, eeprom_write},
{"flash", flash_init, flash_open, flash_write}
};
storage_t *factory_creat(char *name)
{
int i;
for (i = 0; i < sizeof(storage_list) / sizeof(storage_list[0]); i++)
{
if (0 == strcmp(name, storage_list[i].name))
{
storage_list[i].init();
storage_list[i].open();
return &storage_list[i];
}
}
return NULL;
}
void factory_main_func(void)
{
char *str[] = {"EEPROM", "FLASH"};
storage_t *byte_date = factory_creat("eeprom");
storage_t *sector_date = factory_creat("flash");
byte_date->write(0x0100, str[0], sizeof(str[0]));
sector_date->write(0x0200, str[1], sizeof(str[1]));
}

示例代码四

Code
/*
5.工厂模式:女娲造人篇
*/
typedef enum manType_
{
Yellow = 1,
Black,
White,
}manType;
// 抽象种人
typedef struct AbstractHuman_
{
void (*Get_Corlor)(void);
void (* Talk_Language)(void);
}AbstractHuman;
// yellow Base版
void Get_Corlor_Y(void)
{
printf("Get_Corlor_Y\r\n");
// todo
}
// yellow Base版
void Talk_Language_Y(void)
{
printf("Talk_Language_Y\r\n");
// todo
}
// 为什么要在这里实例化?不应该是抽象定义吗?
// 既然已经实例化了,后面不能按之前写了
// 他这里定义一个原始种人,后面直接用它传参取地址
// 定义yellow人的Base版
AbstractHuman YellowHuman = {
.Get_Corlor = Get_Corlor_Y,
.Talk_Language = Talk_Language_Y,
};
// white Base版
void Get_Corlor_W(void)
{
printf("Get_Corlor_W\r\n");
// todo
}
void Talk_Language_W(void)
{
printf("Talk_Language_W\r\n");
// todo
}
// 定义white人的Base版
AbstractHuman WhiteHuman = {
.Get_Corlor = Get_Corlor_W,
.Talk_Language = Talk_Language_W,
};
// 抽象工厂
typedef struct AbstractFactory_
{
// 注意这里的星号
AbstractHuman * (*Human_Create_Factory)(AbstractHuman *pHuman);
}AbstractFactory;
// 具体工厂-Base版
AbstractHuman * Create_Human(AbstractHuman *pHuman)
{
printf("Create_Human\r\n");
if (pHuman == NULL)
return NULL;
AbstractHuman *human = (AbstractHuman *)malloc(sizeof(AbstractHuman));
if (human == NULL)
return NULL;
memset(human, 0, sizeof(human));
human->Get_Corlor = pHuman->Get_Corlor;
human->Talk_Language = pHuman->Talk_Language;
return human;
}
// 具体工厂定义
AbstractFactory Human_Factory = {
.Human_Create_Factory = Create_Human,
};
// 主函数
void NvWa_main_function(void)
{
AbstractFactory YYLu = Human_Factory;
AbstractHuman * yellowMan = YYLu.Human_Create_Factory(&YellowHuman);
if (yellowMan != NULL)
{
yellowMan->Get_Corlor();
yellowMan->Talk_Language();
free(yellowMan);
}
AbstractHuman * whiteMan = YYLu.Human_Create_Factory(&WhiteHuman);
if (whiteMan != NULL)
{
whiteMan->Get_Corlor();
whiteMan->Talk_Language();
free(whiteMan);
}
}

参考链接

posted @   steve的miao  阅读(20)  评论(0编辑  收藏  举报
相关博文:
阅读排行:
· 被坑几百块钱后,我竟然真的恢复了删除的微信聊天记录!
· 没有Manus邀请码?试试免邀请码的MGX或者开源的OpenManus吧
· 【自荐】一款简洁、开源的在线白板工具 Drawnix
· 园子的第一款AI主题卫衣上架——"HELLO! HOW CAN I ASSIST YOU TODAY
· Docker 太简单,K8s 太复杂?w7panel 让容器管理更轻松!
点击右上角即可分享
微信分享提示