设计模式中工厂模式的C语言实现

news/2024/9/23 3:15:23/

在C语言中实现工厂模式(Factory Pattern)通常需要模拟面向对象的编程方式。工厂模式的核心思想是通过工厂函数来创建不同类型的对象,隐藏对象创建的细节。下面是一个简单的工厂模式在C语言中的实现。

工厂模式示例:几何形状工厂

我们将模拟一个工厂来创建不同的几何形状对象(例如:圆形、矩形、三角形),每个几何形状都有一个 draw 方法。

#include <stdio.h>
#include <stdlib.h>
#include <string.h>// 定义抽象的 Shape 接口
typedef struct Shape {void (*draw)(struct Shape*);  // 函数指针,用于表示多态的 draw 方法
} Shape;// 定义圆形结构体
typedef struct Circle {Shape base;  // 基础 Shape 类型
} Circle;// 定义矩形结构体
typedef struct Rectangle {Shape base;  // 基础 Shape 类型
} Rectangle;// 定义三角形结构体
typedef struct Triangle {Shape base;  // 基础 Shape 类型
} Triangle;// 实现 Circle 的 draw 方法
void drawCircle(Shape* shape) {printf("Drawing a Circle.\n");
}// 实现 Rectangle 的 draw 方法
void drawRectangle(Shape* shape) {printf("Drawing a Rectangle.\n");
}// 实现 Triangle 的 draw 方法
void drawTriangle(Shape* shape) {printf("Drawing a Triangle.\n");
}// 工厂函数,用于创建不同类型的 Shape 对象
Shape* createShape(const char* shapeType) {if (strcmp(shapeType, "Circle") == 0) {Circle* circle = (Circle*)malloc(sizeof(Circle));circle->base.draw = drawCircle;  // 绑定 Circle 的 draw 方法return (Shape*)circle;} else if (strcmp(shapeType, "Rectangle") == 0) {Rectangle* rectangle = (Rectangle*)malloc(sizeof(Rectangle));rectangle->base.draw = drawRectangle;  // 绑定 Rectangle 的 draw 方法return (Shape*)rectangle;} else if (strcmp(shapeType, "Triangle") == 0) {Triangle* triangle = (Triangle*)malloc(sizeof(Triangle));triangle->base.draw = drawTriangle;  // 绑定 Triangle 的 draw 方法return (Shape*)triangle;}return NULL;
}// 释放内存
void destroyShape(Shape* shape) {if (shape != NULL) {free(shape);}
}int main() {// 创建 Circle 对象Shape* circle = createShape("Circle");if (circle != NULL) {circle->draw(circle);  // 输出: Drawing a Circle.destroyShape(circle);}// 创建 Rectangle 对象Shape* rectangle = createShape("Rectangle");if (rectangle != NULL) {rectangle->draw(rectangle);  // 输出: Drawing a Rectangle.destroyShape(rectangle);}// 创建 Triangle 对象Shape* triangle = createShape("Triangle");if (triangle != NULL) {triangle->draw(triangle);  // 输出: Drawing a Triangle.destroyShape(triangle);}return 0;
}

代码说明:

  1. 接口模拟Shape 结构体中包含一个函数指针 draw,用于模拟面向对象语言中的接口及多态行为。

  2. 具体类CircleRectangleTriangle 结构体都继承自 Shape(通过包含 Shape 结构体),每种形状都有自己具体的 draw 方法。

  3. 工厂函数createShape 函数通过传入的形状类型字符串(如 "Circle"、"Rectangle" 等)动态创建相应的对象,并返回 Shape* 类型的指针。

  4. 多态调用:在主函数中,通过调用 draw 函数指针,能够实现对具体对象的多态调用。

  5. 内存管理:工厂函数动态分配内存,因此在使用完对象后需要手动释放内存,避免内存泄漏。

这个设计模式在C语言中通过函数指针和结构体组合的方式来实现了类似面向对象的多态行为。


http://www.ppmy.cn/news/1529127.html

相关文章

SOCKS5代理为何比HTTP代理更快?

在代理类型的选择上&#xff0c;SOCKS5代理经常被认为比HTTP代理更快&#xff0c;这是因为它们在工作原理和功能实现上存在较大的差异。让我们来探讨一下&#xff0c;为什么SOCKS5代理的速度通常比HTTP代理要快。 1. 协议的差异 SOCKS5代理&#xff1a;它是一个通用的代理协议…

计算机毕业设计之:基于微信小程序的校园流浪猫收养系统

博主介绍&#xff1a; ✌我是阿龙&#xff0c;一名专注于Java技术领域的程序员&#xff0c;全网拥有10W粉丝。作为CSDN特邀作者、博客专家、新星计划导师&#xff0c;我在计算机毕业设计开发方面积累了丰富的经验。同时&#xff0c;我也是掘金、华为云、阿里云、InfoQ等平台…

球类目标检测系统源码分享

球类目标检测检测系统源码分享 [一条龙教学YOLOV8标注好的数据集一键训练_70全套改进创新点发刊_Web前端展示] 1.研究背景与意义 项目参考AAAI Association for the Advancement of Artificial Intelligence 项目来源AACV Association for the Advancement of Computer Vis…

DNS是什么?怎么设置

NS是什么意思?有什么用呢?专业的说DNS就是域名系统 (Domain Name System)的简称&#xff0c;也就是IT人士常说的域名解析系统。主要是让用户在互联网上通过域名找到域名对应的IP地址&#xff0c;因为IP地址都是一串数字(例如&#xff1a;192.168.0.1)不方便记忆&#xff0c;便…

Spring6梳理10—— 依赖注入之注入数组类型属性

以上笔记来源&#xff1a; 尚硅谷Spring零基础入门到进阶&#xff0c;一套搞定spring6全套视频教程&#xff08;源码级讲解&#xff09;https://www.bilibili.com/video/BV1kR4y1b7Qc 目录 10 依赖注入之注入数组类型属性 10.1 创建Emp实体类&#xff0c;Dept实体类 10.2…

Nginx泛域名 解析的匹配前缀绑定或转发到子目录

网站的目录结构为&#xff1a; # tree /home/wwwroot/landui.com /home/wwwroot/landui.com ├── bbs │ └── index.html └── www └── index.html 2 directories, 2 files /home/wwwroot/landui.com为nginx的安装目录下默认的存放源代码的路径。 bbs为论坛…

电气自动化入门07:开关电源、三相异步电动机多地与顺序控制电路

视频链接&#xff1a;3.5 电工知识&#xff1a;三相交流异步电动机多地与顺序控制及开关电源选型_哔哩哔哩_bilibilihttps://www.bilibili.com/video/BV1PJ41117PW?p9&vd_sourceb5775c3a4ea16a5306db9c7c1c1486b5 1.开关电源功能与选型说明&#xff1a; 2.三相异步电动机…

WPF 异步

在 WPF 中&#xff0c;异步编程非常重要&#xff0c;尤其是为了保持 UI 线程的响应性。由于 WPF 的 UI 操作必须在主线程上进行&#xff0c;耗时的任务&#xff08;如文件读写、网络请求等&#xff09;如果直接在 UI 线程上执行&#xff0c;会导致 UI 冻结&#xff0c;界面无法…