目录
简单工厂模式(Simple Factory Pattern)不是严格意义上的设计模式,但它是一种常用的编程技巧,用于封装对象创建的逻辑。简单工厂模式的主要目的是通过一个工厂类根据传入的参数决定创建哪一个产品类的实例。简单工厂模式可以简化客户端代码,使其不必关心对象的创建细节,只需调用工厂类的静态方法即可获得所需的产品对象。
关键概念
- Factory 类:工厂类负责创建产品类的实例。
- Product 接口或抽象类:定义产品的公共接口。
- Concrete Product 类:实现产品的具体逻辑。
使用场景
简单工厂模式适用于以下情况:
- 工厂类负责创建的对象较少,且这些对象是相似的,只是实现不同。
- 工厂类不会随着产品类的增多而变得复杂。
- 客户端只知道传入工厂类的参数,不知道如何创建产品类。
示例1:创建几何形状对象
假设我们需要创建几何形状的类(如圆形、矩形等),我们可以使用简单工厂模式来创建这些对象。这里我们将创建一个简单的几何形状工厂类,它可以根据输入的类型返回对应的几何形状对象。
示例代码
c
深色版本
1#include <stdio.h>
2#include <stdlib.h>
3
4// 定义几何形状接口
5typedef struct Shape *Shape;
6
7typedef void (*Draw)(Shape shape);
8
9struct Shape {
10 Draw draw;
11};
12
13// 圆形
14struct Circle {
15 Shape base;
16};
17
18void circle_draw(struct Circle *circle) {
19 printf("Drawing Circle...\n");
20}
21
22Shape create_circle() {
23 struct Circle *circle = malloc(sizeof(struct Circle));
24 circle->base.draw = (Draw)circle_draw;
25 return &circle->base;
26}
27
28// 矩形
29struct Rectangle {
30 Shape base;
31};
32
33void rectangle_draw(struct Rectangle *rectangle) {
34 printf("Drawing Rectangle...\n");
35}
36
37Shape create_rectangle() {
38 struct Rectangle *rectangle = malloc(sizeof(struct Rectangle));
39 rectangle->base.draw = (Draw)rectangle_draw;
40 return &rectangle->base;
41}
42
43// 几何形状工厂
44Shape create_shape(const char *type) {
45 if (strcmp(type, "Circle") == 0) {
46 return create_circle();
47 } else if (strcmp(type, "Rectangle") == 0) {
48 return create_rectangle();
49 } else {
50 return NULL;
51 }
52}
53
54int main() {
55 Shape shape;
56
57 shape = create_shape("Circle");
58 if (shape != NULL) {
59 shape->draw(shape);
60 }
61
62 shape = create_shape("Rectangle");
63 if (shape != NULL) {
64 shape->draw(shape);
65 }
66
67 return 0;
68}
解释
- Shape 接口:定义了
draw
方法,这是所有几何形状共有的接口。 - 具体形状类:
Circle
和Rectangle
分别实现了draw
方法,用于绘制对应的形状。 - 工厂函数
create_shape
:根据传入的类型字符串,返回相应的几何形状对象。在这个例子中,我们通过字符串来区分要创建的对象类型,并调用相应的创建函数。
输出结果
plaintext
深色版本
1Drawing Circle...
2Drawing Rectangle...
总结
简单工厂模式通过工厂类来集中管理和创建对象,简化了客户端代码。这种模式适用于创建的对象较少,且对象的创建逻辑相对简单的情况。在 C 语言中实现简单工厂模式,通常需要手动管理内存(分配和释放),并且通过函数指针或者其他手段来模拟面向对象的多态特性。
示例2:计算器程序
假设我们需要创建一个计算器程序,它可以执行基本的算术运算。我们可以定义一个抽象的运算操作接口,然后为每种运算定义一个具体的实现类。最后,我们将使用一个工厂类来创建这些运算操作对象。
示例代码
c
深色版本
1#include <stdio.h>
2#include <stdlib.h>
3#include <string.h>
4
5// 定义运算操作接口
6typedef struct Operation *Operation;
7
8typedef double (*Operate)(Operation op);
9
10struct Operation {
11 Operate operate;
12};
13
14// 加法运算
15struct Addition {
16 Operation base;
17};
18
19double addition_operate(struct Addition *addition) {
20 return addition->operands[0] + addition->operands[1];
21}
22
23Operation create_addition(double a, double b) {
24 struct Addition *addition = malloc(sizeof(struct Addition));
25 addition->base.operate = (Operate)addition_operate;
26 addition->operands[0] = a;
27 addition->operands[1] = b;
28 return &addition->base;
29}
30
31// 减法运算
32struct Subtraction {
33 Operation base;
34 double operands[2];
35};
36
37double subtraction_operate(struct Subtraction *subtraction) {
38 return subtraction->operands[0] - subtraction->operands[1];
39}
40
41Operation create_subtraction(double a, double b) {
42 struct Subtraction *subtraction = malloc(sizeof(struct Subtraction));
43 subtraction->base.operate = (Operate)subtraction_operate;
44 subtraction->operands[0] = a;
45 subtraction->operands[1] = b;
46 return &subtraction->base;
47}
48
49// 乘法运算
50struct Multiplication {
51 Operation base;
52 double operands[2];
53};
54
55double multiplication_operate(struct Multiplication *multiplication) {
56 return multiplication->operands[0] * multiplication->operands[1];
57}
58
59Operation create_multiplication(double a, double b) {
60 struct Multiplication *multiplication = malloc(sizeof(struct Multiplication));
61 multiplication->base.operate = (Operate)multiplication_operate;
62 multiplication->operands[0] = a;
63 multiplication->operands[1] = b;
64 return &multiplication->base;
65}
66
67// 除法运算
68struct Division {
69 Operation base;
70 double operands[2];
71};
72
73double division_operate(struct Division *division) {
74 return division->operands[0] / division->operands[1];
75}
76
77Operation create_division(double a, double b) {
78 struct Division *division = malloc(sizeof(struct Division));
79 division->base.operate = (Operate)division_operate;
80 division->operands[0] = a;
81 division->operands[1] = b;
82 return &division->base;
83}
84
85// 简单工厂函数
86Operation create_operation(const char *operation, double a, double b) {
87 if (strcmp(operation, "Addition") == 0) {
88 return create_addition(a, b);
89 } else if (strcmp(operation, "Subtraction") == 0) {
90 return create_subtraction(a, b);
91 } else if (strcmp(operation, "Multiplication") == 0) {
92 return create_multiplication(a, b);
93 } else if (strcmp(operation, "Division") == 0) {
94 return create_division(a, b);
95 } else {
96 return NULL;
97 }
98}
99
100int main() {
101 double a = 10;
102 double b = 5;
103 Operation operation;
104
105 // 创建加法运算
106 operation = create_operation("Addition", a, b);
107 if (operation != NULL) {
108 double result = operation->operate(operation);
109 printf("Result of Addition: %f\n", result);
110 }
111
112 // 创建减法运算
113 operation = create_operation("Subtraction", a, b);
114 if (operation != NULL) {
115 double result = operation->operate(operation);
116 printf("Result of Subtraction: %f\n", result);
117 }
118
119 // 创建乘法运算
120 operation = create_operation("Multiplication", a, b);
121 if (operation != NULL) {
122 double result = operation->operate(operation);
123 printf("Result of Multiplication: %f\n", result);
124 }
125
126 // 创建除法运算
127 operation = create_operation("Division", a, b);
128 if (operation != NULL) {
129 double result = operation->operate(operation);
130 printf("Result of Division: %f\n", result);
131 }
132
133 return 0;
134}
解释
- Operation 接口:定义了
operate
方法,这是所有运算操作共有的接口。 - 具体运算类:
Addition
、Subtraction
、Multiplication
和Division
分别实现了operate
方法,用于执行具体的运算。 - 工厂函数
create_operation
:根据传入的运算类型字符串,返回相应的运算操作对象。在这个例子中,我们通过字符串来区分要创建的对象类型,并调用相应的创建函数。
输出结果
plaintext
深色版本
1Result of Addition: 15.000000
2Result of Subtraction: 5.000000
3Result of Multiplication: 50.000000
4Result of Division: 2.000000
总结
在这个示例中,我们使用简单工厂模式来创建不同的运算操作对象。简单工厂模式通过工厂类来集中管理和创建对象,简化了客户端代码。这种模式适用于创建的对象较少,且对象的创建逻辑相对简单的情况。在 C 语言中实现简单工厂模式,通常需要手动管理内存(分配和释放),并且通过函数指针来模拟面向对象的多态特性。