简单工厂模式
简单工厂模式通过一个工厂类来创建不同类型的对象。工厂类包含一个方法,根据传入的参数决定创建哪种类型的对象。
应用场景:
传感器驱动程序:在嵌入式系统中,可能需要支持多种传感器(如温度传感器、压力传感器等)。可以使用简单工厂模式来创建不同类型的传感器对象。
优点:
- 简单易懂,便于实现。
- 客户端代码与具体类解耦,便于扩展。
缺点:
- 工厂类的职责过重,增加新类型时需要修改工厂类代码,违反开闭原则。
实例:传感器驱动程序
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
// 传感器接口
typedef struct {
void (*read)(void);
} Sensor;
// 温度传感器实现
void read_temperature() {
printf("Reading temperature sensor\n");
}
// 压力传感器实现
void read_pressure() {
printf("Reading pressure sensor\n");
}
// 简单工厂
Sensor* create_sensor(const char* type) {
Sensor* sensor = (Sensor*)malloc(sizeof(Sensor));
if (strcmp(type, "temperature") == 0) {
sensor->read = read_temperature;
} else if (strcmp(type, "pressure") == 0) {
sensor->read = read_pressure;
}
return sensor;
}
// 使用简单工厂模式
int main() {
Sensor* temp_sensor = create_sensor("temperature");
Sensor* pressure_sensor = create_sensor("pressure");
temp_sensor->read();
pressure_sensor->read();
free(temp_sensor);
free(pressure_sensor);
return 0;
}
工厂方法模式
工厂方法模式定义一个用于创建对象的接口,但由子类决定实例化哪个类。工厂方法使一个类的实例化延迟到其子类。
应用场景:
通信接口驱动程序:在嵌入式系统中,可能需要支持多种通信接口(如UART、SPI、I2C等)。可以使用工厂方法模式来创建不同类型的通信接口对象。
优点:
- 遵循开闭原则,增加新类型时不需要修改现有代码。
- 更加灵活,便于扩展。
缺点:
- 增加了系统的复杂性,需要定义多个工厂类。
实例:通信接口驱动程序
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
// 通信接口
typedef struct {
void (*init)(void);
void (*send)(const char* data);
} Communication;
// UART实现
void uart_init() {
printf("Initializing UART\n");
}
void uart_send(const char* data) {
printf("Sending via UART: %s\n", data);
}
Communication* create_uart() {
Communication* comm = (Communication*)malloc(sizeof(Communication));
comm->init = uart_init;
comm->send = uart_send;
return comm;
}
// SPI实现
void spi_init() {
printf("Initializing SPI\n");
}
void spi_send(const char* data) {
printf("Sending via SPI: %s\n", data);
}
Communication* create_spi() {
Communication* comm = (Communication*)malloc(sizeof(Communication));
comm->init = spi_init;
comm->send = spi_send;
return comm;
}
// 工厂方法
typedef Communication* (*CreateCommFunc)(void);
Communication* create_communication(const char* type) {
if (strcmp(type, "UART") == 0) {
return create_uart();
} else if (strcmp(type, "SPI") == 0) {
return create_spi();
}
return NULL;
}
// 使用工厂方法模式
int main() {
Communication* uart_comm = create_communication("UART");
Communication* spi_comm = create_communication("SPI");
uart_comm->init();
uart_comm->send("Hello UART");
spi_comm->init();
spi_comm->send("Hello SPI");
free(uart_comm);
free(spi_comm);
return 0;
}
抽象工厂模式
抽象工厂模式提供一个创建一系列相关或相互依赖对象的接口,而无需指定它们具体的类。
应用场景:
GUI组件:在嵌入式系统中,可能需要支持不同的显示设备(如LCD、OLED等),可以使用抽象工厂模式来创建不同类型的GUI组件。
优点:
- 可以创建一系列相关或相互依赖的对象,保证产品的一致性。
- 遵循开闭原则,便于扩展。
缺点:
- 增加了系统的复杂性,需要定义多个工厂类和产品类。
实例:嵌入式系统中的GUI组件
#include <stdio.h>
#include <stdlib.h>
// 按钮接口
typedef struct {
void (*draw)(void);
} Button;
// LCD按钮实现
void draw_lcd_button() {
printf("Drawing LCD button\n");
}
// OLED按钮实现
void draw_oled_button() {
printf("Drawing OLED button\n");
}
// 工厂接口
typedef struct {
Button* (*create_button)(void);
} GUIFactory;
// LCD工厂实现
Button* create_lcd_button() {
Button* button = (Button*)malloc(sizeof(Button));
button->draw = draw_lcd_button;
return button;
}
GUIFactory* create_lcd_factory() {
GUIFactory* factory = (GUIFactory*)malloc(sizeof(GUIFactory));
factory->create_button = create_lcd_button;
return factory;
}
// OLED工厂实现
Button* create_oled_button() {
Button* button = (Button*)malloc(sizeof(Button));
button->draw = draw_oled_button;
return button;
}
GUIFactory* create_oled_factory() {
GUIFactory* factory = (GUIFactory*)malloc(sizeof(GUIFactory));
factory->create_button = create_oled_button;
return factory;
}
// 使用抽象工厂模式
int main() {
GUIFactory* lcd_factory = create_lcd_factory();
GUIFactory* oled_factory = create_oled_factory();
Button* lcd_button = lcd_factory->create_button();
Button* oled_button = oled_factory->create_button();
lcd_button->draw();
oled_button->draw();
free(lcd_button);
free(oled_button);
free(lcd_factory);
free(oled_factory);
return 0;
}
总结
- 简单工厂模式:通过一个工厂类来创建不同类型的对象。
- 工厂方法模式:定义一个用于创建对象的接口,但由子类决定实例化哪个类。
- 抽象工厂模式:提供一个创建一系列相关或相互依赖对象的接口,而无需指定它们具体的类。
这些模式在嵌入式软件开发中非常有用,可以帮助我们创建不同类型的对象,减少代码耦合,提高代码的可维护性和扩展性。
公众号 | FunIO
微信搜一搜 “funio”,发现更多精彩内容。
个人博客 | blog.boringhex.top