1.简介
工厂方法模式是一种创建型设计模式,它定义了一个接口用于创建对象,但允许子类决定实例化哪一个类。这种模式让一个类的实例化延迟到其子类,从而实现了解耦和扩展性。
在 C 语言中,由于没有类的概念,工厂方法模式通常通过函数指针和结构体来实现。我们将通过一个简单的例子来说明这一点。
2.通俗讲解
几何图形的创建:
假设我们要创建一个几何图形的程序,该程序能够生成不同的形状,如圆形(Circle)和矩形(Rectangle)。我们可以使用工厂方法模式来实现这个功能,使得我们可以方便地扩展新的形状,而无需修改现有代码。
3.实战
3.1.代码
#include <stdio.h>
#include <stdlib.h>
/*
1. 定义通用的图形接口
首先,我们定义一个通用的图形接口,这里用一个结构体来表示,它包含了一个用于计算面积的函数指针。
*/
// 定义图形结构体
typedef struct Shape {
double (*getArea)(struct Shape*); // 计算面积的函数指针
} Shape;
/*
2. 实现具体的图形结构体
接下来,我们实现两个具体的图形:圆形和矩形。每个图形都有自己的结构体和计算面积的实现。
*/
// 圆形结构体及其计算面积的方法
typedef struct {
Shape base; // 基础图形结构体
double radius; // 半径
} Circle;
double getCircleArea(Shape* shape) {
Circle* circle = (Circle*)shape;
return 3.14159 * circle->radius * circle->radius;
}
// 矩形结构体及其计算面积的方法
typedef struct {
Shape base; // 基础图形结构体
double width; // 宽度
double height;// 高度
} Rectangle;
double getRectangleArea(Shape* shape) {
Rectangle* rectangle = (Rectangle*)shape;
return rectangle->width * rectangle->height;
}
/*
3. 工厂方法的实现
现在我们来实现工厂方法,用于创建具体的图形对象。这个工厂方法返回一个指向 Shape 结构体的指针。
*/
// 工厂方法,用于创建圆形
Shape* createCircle(double radius) {
Circle* circle = (Circle*)malloc(sizeof(Circle));
circle->radius = radius;
circle->base.getArea = getCircleArea;
return (Shape*)circle;
}
// 工厂方法,用于创建矩形
Shape* createRectangle(double width, double height) {
Rectangle* rectangle = (Rectangle*)malloc(sizeof(Rectangle));
rectangle->width = width;
rectangle->height = height;
rectangle->base.getArea = getRectangleArea;
return (Shape*)rectangle;
}
/*
4. 客户端代码
最后,我们编写客户端代码,使用工厂方法创建图形并计算它们的面积。
*/
int main() {
Shape* circle = createCircle(5.0);
Shape* rectangle = createRectangle(4.0, 6.0);
printf("Circle Area: %.2f\n", circle->getArea(circle));
printf("Rectangle Area: %.2f\n", rectangle->getArea(rectangle));
// 释放内存
free(circle);
free(rectangle);
return 0;
}
3.2.代码解析
在这个例子中,我们使用工厂方法 createCircle 和 createRectangle 来创建不同的图形对象。这些工厂方法返回的都是一个通用的 Shape 指针,因此客户端代码只需使用这个指针调用 getArea 函数,无需关心具体的图形类型。
这种设计的好处是,我们可以很容易地添加新的图形类型,例如三角形,只需添加新的结构体和工厂方法,而不需要修改客户端代码。这就实现了代码的解耦和可扩展性。
3.3.代码运行
当你运行上面的代码时,会得到如下输出:
Circle Area: 78.54
Rectangle Area: 24.00
3.4.结果分析
- 圆形的面积是通过 getCircleArea 函数计算的,结果为 78.54,对应的半径为 5.0。
- 矩形的面积是通过 getRectangleArea 函数计算的,结果为 24.00,对应的宽度为 4.0,高度为 6.0。
这个输出展示了工厂方法模式的实际效果,通过不同的工厂方法创建了不同的图形对象,并使用各自的逻辑计算出了面积。
4.总结
工厂方法模式在 C 语言中的实现尽管比在面向对象语言中要复杂一些,但它依然能够有效地帮助我们实现对象的创建和管理。通过使用函数指针和结构体,我们能够在 C 语言中实现这一经典的设计模式。