嵌入式系统软件开发:工厂模式的应用与分析

简单工厂模式

简单工厂模式通过一个工厂类来创建不同类型的对象。工厂类包含一个方法,根据传入的参数决定创建哪种类型的对象。

应用场景:

传感器驱动程序:在嵌入式系统中,可能需要支持多种传感器(如温度传感器、压力传感器等)。可以使用简单工厂模式来创建不同类型的传感器对象。

优点:

  • 简单易懂,便于实现。
  • 客户端代码与具体类解耦,便于扩展。

缺点:

  • 工厂类的职责过重,增加新类型时需要修改工厂类代码,违反开闭原则。

实例:传感器驱动程序

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
#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等)。可以使用工厂方法模式来创建不同类型的通信接口对象。

优点:

  • 遵循开闭原则,增加新类型时不需要修改现有代码。
  • 更加灵活,便于扩展。

缺点:

  • 增加了系统的复杂性,需要定义多个工厂类。

实例:通信接口驱动程序

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
#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组件

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
#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;
}

总结

  • 简单工厂模式:通过一个工厂类来创建不同类型的对象。
  • 工厂方法模式:定义一个用于创建对象的接口,但由子类决定实例化哪个类。
  • 抽象工厂模式:提供一个创建一系列相关或相互依赖对象的接口,而无需指定它们具体的类。

这些模式在嵌入式软件开发中非常有用,可以帮助我们创建不同类型的对象,减少代码耦合,提高代码的可维护性和扩展性。