建造者模式-C语言实现
UML类图:
代码实现:
#include <stdio.h>
#include <stdlib.h>// 产品类
typedef struct {char* part1;char* part2;char* part3;
} Product;// 抽象建造者类
typedef struct {void (*buildPart1)(void*, const char*);void (*buildPart2)(void*, const char*);void (*buildPart3)(void*, const char*);Product* (*getResult)(void*);
} Builder;// 具体建造者类
typedef struct {Product* product;void (*buildPart1)(void*, const char*);void (*buildPart2)(void*, const char*);void (*buildPart3)(void*, const char*);Product* (*getResult)(void*);
} ConcreteBuilder;void ConcreteBuilder_buildPart1(void* obj, const char* value) {ConcreteBuilder* builder = (ConcreteBuilder*)obj;builder->product->part1 = malloc(sizeof(char) * (strlen(value) + 1));strcpy(builder->product->part1, value);
}void ConcreteBuilder_buildPart2(void* obj, const char* value) {ConcreteBuilder* builder = (ConcreteBuilder*)obj;builder->product->part2 = malloc(sizeof(char) * (strlen(value) + 1));strcpy(builder->product->part2, value);
}void ConcreteBuilder_buildPart3(void* obj, const char* value) {ConcreteBuilder* builder = (ConcreteBuilder*)obj;builder->product->part3 = malloc(sizeof(char) * (strlen(value) + 1));strcpy(builder->product->part3, value);
}Product* ConcreteBuilder_getResult(void* obj) {ConcreteBuilder* builder = (ConcreteBuilder*)obj;return builder->product;
}// 指挥者类
typedef struct {void (*construct)(void*, Builder*);
} Director;void Director_construct(void* obj, Builder* builder) {Director* director = (Director*)obj;director->builder = builder;director->builder->buildPart1(director->builder, "Part 1");director->builder->buildPart2(director->builder, "Part 2");director->builder->buildPart3(director->builder, "Part 3");
}int main() {ConcreteBuilder builder;Product* product;builder.product = malloc(sizeof(Product));builder.buildPart1 = ConcreteBuilder_buildPart1;builder.buildPart2 = ConcreteBuilder_buildPart2;builder.buildPart3 = ConcreteBuilder_buildPart3;builder.getResult = ConcreteBuilder_getResult;Director director;director.construct = Director_construct;director.construct(&director, (Builder*)&builder);product = builder.getResult(&builder);printf("Part 1: %s\n", product->part1);printf("Part 2: %s\n", product->part2);printf("Part 3: %s\n", product->part3);free(product->part1);free(product->part2);free(product->part3);free(product);return 0;
}
在上面的示例代码中,首先定义了产品类Product
,其中包含了三个部分。然后定义了抽象建造者类Builder
,其中包含了构建产品的各个部分的函数指针。
接着定义了具体建造者类ConcreteBuilder
,它实现了抽象建造者类中的函数,并拥有一个指向产品对象的指针。具体建造者类通过实现不同的构建方法来构建产品的不同部分,并提供获取最终产品的函数。
最后定义了指挥者类Director
,它接收一个具体建造者对象作为参数,通过调用具体建造者的函数来构建产品。
在main
函数中,创建了具体建造者对象builder
和指挥者对象director
,然后通过指挥者对象来构建产品。最后获取并打印产品的各个部分。
建造者模式将产品的构建过程与产品的表示分离,使得构建过程可以独立于产品而变化。通过使用建造者模式,可以更加灵活地构建复杂对象,并且可以复用相同的构建过程来创建不同的产品。
建造者模式的优点:
-
可以将复杂对象的创建过程分解为多个简单的步骤,使得代码更加清晰、易于维护和扩展。
-
可以复用相同的构建过程来创建不同的产品,具有良好的灵活性。
-
可以控制产品对象的创建过程,保证其完整性和一致性。
-
可以隐藏产品的内部实现细节,使得客户端只需要关心产品的接口。
建造者模式的缺点:
-
建造者模式中会增加很多类,导致代码量增加。
-
如果产品的组成部分发生变化,可能需要修改建造者类的代码,影响系统的稳定性。
适用场景:
-
需要创建复杂的对象,而且对象的构建过程是稳定的,但是具体的构建步骤可能会有所差异。
-
需要创建多个相似但不同的对象,可以使用同一个构建过程来构建不同的对象。
-
需要控制对象的创建过程,并且希望隐藏产品的创建细节,只暴露出产品的接口。
-
当产品的构成部分需要动态变化时,可以使用建造者模式。
相关文章:

建造者模式-C语言实现
UML类图: 代码实现: #include <stdio.h> #include <stdlib.h>// 产品类 typedef struct {char* part1;char* part2;char* part3; } Product;// 抽象建造者类 typedef struct {void (*buildPart1)(void*, const char*);void (*buildPart2)(v…...

Jmeter+influxdb+grafana监控平台在windows环境的搭建
原理:Jmeter采集的数据存储在infuxdb数据库中,grafana将数据库中的数据在界面上进行展示 一、grafana下载安装 Download Grafana | Grafana Labs 直接选择zip包下载,下载后解压即可,我之前下载过比较老的版本,这里就…...

关注这两点 或能避开一些现货黄金交易的陷阱
在现货黄金投资中,交易机会是处处都有,但是亏损的情况也可能出现。投资者要在陷阱处处的市场中获得稳定盈利,就需要懂得如何规避现货黄金投资的陷阱。下面我们就来介绍两个很常用的避开陷阱的方法。 看交易的活跃度。交易越活跃,市…...

Python 文件读写
Python 文件读写笔记整理 参数说明 open(path, flag[, encoding][,errors]) path:要打开文件的路径 flag:打开方式 encoding:编码方式 errors:错误处理 Flag打开方式表 模式 描述 r 以只读方式打开文件。文件的指针将会放在文件的开头。这是默认模式。 rb 以二进制格…...

线性分组码的奇偶校验矩阵均匀性分析
回顾信道编解码知识,我们知道信道编码要求编码具有检纠错能力,作为FEC(forward error correction)前向纠错编码的一类,线性分组码表示校验位与信息位的关系能够线性表示。 在这篇文章中,并不是要讨论信道编…...

leetcode算法之链表
目录 1.两数相加2.两两交换链表中的节点3.重排链表4.合并K个升序链表5.K个一组翻转链表 1.两数相加 两数相加 /*** Definition for singly-linked list.* struct ListNode {* int val;* ListNode *next;* ListNode() : val(0), next(nullptr) {}* ListNode(…...
2023.11.27 滴滴P0级故障或为k8s升级造成
滴滴11.27 P0级故障|打车|宕机|网约车|出租车|滴滴出行|系统故障_网易订阅 (163.com) 如何看待滴滴11月27日故障,对日常生产生活有哪些影响? - 知乎 (zhihu.com) 最新消息滴滴P0故障原因,是由于k8s集群升级导致的,后面又进行版本…...

Ubuntu16.04.4系统本地提权实验
目录 1.介绍: 2.实验: 3.总结: 1.介绍: 1.1:eBPF简介:eBPF(extendedBerkeleyPacketFilter)是内核源自于BPF的一套包过滤机制,BPF可以理解成用户与内核之间的一条通道,有非常强大的…...
Vue中使用正则表达式进行文本匹配和处理的方法
1. 正则表达式基础 正则表达式是一种用来匹配字符串的模式。它由普通字符(例如字符 a 到 z)和特殊字符(称为"元字符")组成。以下是一些基本的正则表达式示例: 匹配邮箱的正则表达式: /^[\w-](\…...
php许愿墙代码包括前端和后端部分
以下是一个简单的PHP许愿墙代码示例,包括前端和后端部分: 前端HTML代码(index.html): <!DOCTYPE html> <html> <head><title>许愿墙</title> </head> <body><h1>许…...
PHP 刷新缓存区的问题!
PHP流式输出,在Nginx下可以正常刷新缓存区 , 但是在Apache下会等待循环全部执行完,才会刷新!有怎么解决? header(X-Accel-Buffering: no); // Nginx情况下必须加这一行header(Content-type: text/event-stream);header…...

Android Studio Giraffe-2022.3.1-Patch-3安装注意事项
准备工作: android studio下载地址:https://developer.android.google.cn/studio/releases?hlzh-cn gradle下载地址:https://services.gradle.org/distributions/ 比较稳定的网络环境(比较android studio相关的依赖需要从谷歌那边…...

【古月居《ros入门21讲》学习笔记】14_参数的使用与编程方法
目录 说明: 1. 参数模型(全局字典) 2. 实现过程(C) 创建功能包 参数命令行的使用 YAML参数文件 rosparam命令 使用示例 编程方法(C) 配置代码编译规则 编译并运行 编译 运行 3. 实…...
Webpack 懒加载
文章目录 前言懒加载示例后言 前言 hello world欢迎来到前端的新世界 😜当前文章系列专栏:webpack 🐱👓博主在前端领域还有很多知识和技术需要掌握,正在不断努力填补技术短板。(如果出现错误,感谢大家指出…...

深度遍历DFS(括号生成,二叉树所有路径)
正整数 n 代表生成括号的对数,请设计一个函数,用于能够生成所有可能的并且 有效的 括号组合。 示例 1: 输入:n 3 输出:["((()))","(()())","(())()","()(())","()()(…...

Rational Arithmetic
📑打牌 : da pai ge的个人主页 🌤️个人专栏 : da pai ge的博客专栏 ☁️宝剑锋从磨砺出,梅花香自苦寒来 ☁️有理数运算 实现对两个有理数的…...

文心一言4.0(ERNIE-Bot-4)申请方法及简单调用代码示例
10月17日过后,估计很多人会看到类似的新闻,如图: 我看到这则新闻也是觉得非常感兴趣,于是本着“百闻不如一见”的实事求是的态度检索如何申请,没想到还真找到了ERNIE-Bot-4(俗称:文心一言4.0&a…...

年终好价节买什么好?这些数码好物闭眼入
大家是不是都没听说过好价节?直截了当地说,这其实就是原先的双十二购物狂欢节,只不过给它起了个新名字。不过,今年毕竟是首次改名,因此淘宝年终好价节的各种优惠,仍然是我们值得期待的!作为年前…...
webpack对项目进行优化
对项目进行优化是提高性能和效率的关键,以下是一些实用的Webpack优化技巧: 代码拆分(Code Splitting):将代码拆分为多个小块,按需加载。通过配置splitChunks插件,可以将公共代码提取到单独的文件…...
Python edge-tts库全部声音模型一览表
下面是edge-tts的声音模型,zh-CN为中文语音模型 Name: af-ZA-AdriNeural Gender: Female Name: af-ZA-WillemNeural Gender: Male Name: am-ET-AmehaNeural Gender: Male Name: am-ET-MekdesNeural Gender: Female Name: ar-AE-FatimaNeural Gender: Female N…...

Qt/C++开发监控GB28181系统/取流协议/同时支持udp/tcp被动/tcp主动
一、前言说明 在2011版本的gb28181协议中,拉取视频流只要求udp方式,从2016开始要求新增支持tcp被动和tcp主动两种方式,udp理论上会丢包的,所以实际使用过程可能会出现画面花屏的情况,而tcp肯定不丢包,起码…...
Auto-Coder使用GPT-4o完成:在用TabPFN这个模型构建一个预测未来3天涨跌的分类任务
通过akshare库,获取股票数据,并生成TabPFN这个模型 可以识别、处理的格式,写一个完整的预处理示例,并构建一个预测未来 3 天股价涨跌的分类任务 用TabPFN这个模型构建一个预测未来 3 天股价涨跌的分类任务,进行预测并输…...
五年级数学知识边界总结思考-下册
目录 一、背景二、过程1.观察物体小学五年级下册“观察物体”知识点详解:由来、作用与意义**一、知识点核心内容****二、知识点的由来:从生活实践到数学抽象****三、知识的作用:解决实际问题的工具****四、学习的意义:培养核心素养…...

P3 QT项目----记事本(3.8)
3.8 记事本项目总结 项目源码 1.main.cpp #include "widget.h" #include <QApplication> int main(int argc, char *argv[]) {QApplication a(argc, argv);Widget w;w.show();return a.exec(); } 2.widget.cpp #include "widget.h" #include &q…...
镜像里切换为普通用户
如果你登录远程虚拟机默认就是 root 用户,但你不希望用 root 权限运行 ns-3(这是对的,ns3 工具会拒绝 root),你可以按以下方法创建一个 非 root 用户账号 并切换到它运行 ns-3。 一次性解决方案:创建非 roo…...
【决胜公务员考试】求职OMG——见面课测验1
2025最新版!!!6.8截至答题,大家注意呀! 博主码字不易点个关注吧,祝期末顺利~~ 1.单选题(2分) 下列说法错误的是:( B ) A.选调生属于公务员系统 B.公务员属于事业编 C.选调生有基层锻炼的要求 D…...
重启Eureka集群中的节点,对已经注册的服务有什么影响
先看答案,如果正确地操作,重启Eureka集群中的节点,对已经注册的服务影响非常小,甚至可以做到无感知。 但如果操作不当,可能会引发短暂的服务发现问题。 下面我们从Eureka的核心工作原理来详细分析这个问题。 Eureka的…...

七、数据库的完整性
七、数据库的完整性 主要内容 7.1 数据库的完整性概述 7.2 实体完整性 7.3 参照完整性 7.4 用户定义的完整性 7.5 触发器 7.6 SQL Server中数据库完整性的实现 7.7 小结 7.1 数据库的完整性概述 数据库完整性的含义 正确性 指数据的合法性 有效性 指数据是否属于所定…...

群晖NAS如何在虚拟机创建飞牛NAS
套件中心下载安装Virtual Machine Manager 创建虚拟机 配置虚拟机 飞牛官网下载 https://iso.liveupdate.fnnas.com/x86_64/trim/fnos-0.9.2-863.iso 群晖NAS如何在虚拟机创建飞牛NAS - 个人信息分享...

Proxmox Mail Gateway安装指南:从零开始配置高效邮件过滤系统
💝💝💝欢迎莅临我的博客,很高兴能够在这里和您见面!希望您在这里可以感受到一份轻松愉快的氛围,不仅可以获得有趣的内容和知识,也可以畅所欲言、分享您的想法和见解。 推荐:「storms…...