当前位置: 首页 > news >正文

建造者模式-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,然后通过指挥者对象来构建产品。最后获取并打印产品的各个部分。

建造者模式将产品的构建过程与产品的表示分离,使得构建过程可以独立于产品而变化。通过使用建造者模式,可以更加灵活地构建复杂对象,并且可以复用相同的构建过程来创建不同的产品。

建造者模式的优点:

  1. 可以将复杂对象的创建过程分解为多个简单的步骤,使得代码更加清晰、易于维护和扩展。

  2. 可以复用相同的构建过程来创建不同的产品,具有良好的灵活性。

  3. 可以控制产品对象的创建过程,保证其完整性和一致性。

  4. 可以隐藏产品的内部实现细节,使得客户端只需要关心产品的接口。

建造者模式的缺点:

  1. 建造者模式中会增加很多类,导致代码量增加。

  2. 如果产品的组成部分发生变化,可能需要修改建造者类的代码,影响系统的稳定性。

适用场景:

  1. 需要创建复杂的对象,而且对象的构建过程是稳定的,但是具体的构建步骤可能会有所差异。

  2. 需要创建多个相似但不同的对象,可以使用同一个构建过程来构建不同的对象。

  3. 需要控制对象的创建过程,并且希望隐藏产品的创建细节,只暴露出产品的接口。

  4. 当产品的构成部分需要动态变化时,可以使用建造者模式。

相关文章:

建造者模式-C语言实现

UML类图&#xff1a; 代码实现&#xff1a; #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环境的搭建

原理&#xff1a;Jmeter采集的数据存储在infuxdb数据库中&#xff0c;grafana将数据库中的数据在界面上进行展示 一、grafana下载安装 Download Grafana | Grafana Labs 直接选择zip包下载&#xff0c;下载后解压即可&#xff0c;我之前下载过比较老的版本&#xff0c;这里就…...

关注这两点 或能避开一些现货黄金交易的陷阱

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

Python 文件读写

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

线性分组码的奇偶校验矩阵均匀性分析

回顾信道编解码知识&#xff0c;我们知道信道编码要求编码具有检纠错能力&#xff0c;作为FEC&#xff08;forward error correction&#xff09;前向纠错编码的一类&#xff0c;线性分组码表示校验位与信息位的关系能够线性表示。 在这篇文章中&#xff0c;并不是要讨论信道编…...

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日故障&#xff0c;对日常生产生活有哪些影响&#xff1f; - 知乎 (zhihu.com) 最新消息滴滴P0故障原因&#xff0c;是由于k8s集群升级导致的&#xff0c;后面又进行版本…...

Ubuntu16.04.4系统本地提权实验

目录 1.介绍&#xff1a; 2.实验&#xff1a; 3.总结&#xff1a; 1.介绍&#xff1a; 1.1&#xff1a;eBPF简介&#xff1a;eBPF(extendedBerkeleyPacketFilter)是内核源自于BPF的一套包过滤机制&#xff0c;BPF可以理解成用户与内核之间的一条通道&#xff0c;有非常强大的…...

Vue中使用正则表达式进行文本匹配和处理的方法

1. 正则表达式基础 正则表达式是一种用来匹配字符串的模式。它由普通字符&#xff08;例如字符 a 到 z&#xff09;和特殊字符&#xff08;称为"元字符"&#xff09;组成。以下是一些基本的正则表达式示例&#xff1a; 匹配邮箱的正则表达式&#xff1a; /^[\w-](\…...

php许愿墙代码包括前端和后端部分

以下是一个简单的PHP许愿墙代码示例&#xff0c;包括前端和后端部分&#xff1a; 前端HTML代码&#xff08;index.html&#xff09;&#xff1a; <!DOCTYPE html> <html> <head><title>许愿墙</title> </head> <body><h1>许…...

PHP 刷新缓存区的问题!

PHP流式输出&#xff0c;在Nginx下可以正常刷新缓存区 &#xff0c; 但是在Apache下会等待循环全部执行完&#xff0c;才会刷新&#xff01;有怎么解决&#xff1f; header(X-Accel-Buffering: no); // Nginx情况下必须加这一行header(Content-type: text/event-stream);header…...

Android Studio Giraffe-2022.3.1-Patch-3安装注意事项

准备工作&#xff1a; android studio下载地址&#xff1a;https://developer.android.google.cn/studio/releases?hlzh-cn gradle下载地址&#xff1a;https://services.gradle.org/distributions/ 比较稳定的网络环境&#xff08;比较android studio相关的依赖需要从谷歌那边…...

【古月居《ros入门21讲》学习笔记】14_参数的使用与编程方法

目录 说明&#xff1a; 1. 参数模型&#xff08;全局字典&#xff09; 2. 实现过程&#xff08;C&#xff09; 创建功能包 参数命令行的使用 YAML参数文件 rosparam命令 使用示例 编程方法&#xff08;C&#xff09; 配置代码编译规则 编译并运行 编译 运行 3. 实…...

Webpack 懒加载

文章目录 前言懒加载示例后言 前言 hello world欢迎来到前端的新世界 &#x1f61c;当前文章系列专栏&#xff1a;webpack &#x1f431;‍&#x1f453;博主在前端领域还有很多知识和技术需要掌握&#xff0c;正在不断努力填补技术短板。(如果出现错误&#xff0c;感谢大家指出…...

深度遍历DFS(括号生成,二叉树所有路径)

正整数 n 代表生成括号的对数&#xff0c;请设计一个函数&#xff0c;用于能够生成所有可能的并且 有效的 括号组合。 示例 1&#xff1a; 输入&#xff1a;n 3 输出&#xff1a;["((()))","(()())","(())()","()(())","()()(…...

Rational Arithmetic

&#x1f4d1;打牌 &#xff1a; da pai ge的个人主页 &#x1f324;️个人专栏 &#xff1a; da pai ge的博客专栏 ☁️宝剑锋从磨砺出&#xff0c;梅花香自苦寒来 ☁️有理数运算 实现对两个有理数的…...

文心一言4.0(ERNIE-Bot-4)申请方法及简单调用代码示例

10月17日过后&#xff0c;估计很多人会看到类似的新闻&#xff0c;如图&#xff1a; 我看到这则新闻也是觉得非常感兴趣&#xff0c;于是本着“百闻不如一见”的实事求是的态度检索如何申请&#xff0c;没想到还真找到了ERNIE-Bot-4&#xff08;俗称&#xff1a;文心一言4.0&a…...

年终好价节买什么好?这些数码好物闭眼入

大家是不是都没听说过好价节&#xff1f;直截了当地说&#xff0c;这其实就是原先的双十二购物狂欢节&#xff0c;只不过给它起了个新名字。不过&#xff0c;今年毕竟是首次改名&#xff0c;因此淘宝年终好价节的各种优惠&#xff0c;仍然是我们值得期待的&#xff01;作为年前…...

webpack对项目进行优化

对项目进行优化是提高性能和效率的关键&#xff0c;以下是一些实用的Webpack优化技巧&#xff1a; 代码拆分&#xff08;Code Splitting&#xff09;&#xff1a;将代码拆分为多个小块&#xff0c;按需加载。通过配置splitChunks插件&#xff0c;可以将公共代码提取到单独的文件…...

Python edge-tts库全部声音模型一览表

下面是edge-tts的声音模型&#xff0c;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…...

Windows下OpenClaw避坑指南:千问3.5-35B-A3B-FP8接口配置全流程

Windows下OpenClaw避坑指南&#xff1a;千问3.5-35B-A3B-FP8接口配置全流程 1. 为什么选择OpenClaw千问3.5组合&#xff1f; 去年我在尝试自动化处理大量PDF报告时&#xff0c;发现市面上的RPA工具要么太笨重&#xff0c;要么无法处理复杂语义。直到遇到OpenClaw这个开源智能…...

ORA-12518:Oracle 监听程序无法分发客户端连接原因及解决方法

本文主要讲解ORA-12518:Oracle监听程序无法分发客户端连接的原因分析及解决方法。问题描述数据中台的同步任务有时会报错如下&#xff1a;ORA-12518, TNS:listener could not hand off client connection。意即Oracle监听程序无法分发客户端连接&#xff0c;原因分析只是有时候…...

Python 实战:数据归一化 4 种核心方法对比 + 代码实现(机器学习必看)

在机器学习、深度学习的数据预处理中&#xff0c;数据归一化是绕不开的关键步骤。不同特征往往量纲不同&#xff08;比如年龄 18-60、收入 1000-100000&#xff09;&#xff0c;直接训练模型会导致&#xff1a;梯度下降收敛慢、难以最优解距离类算法&#xff08;KNN、K-Means、…...

kmp算法(完结)

1.重复的子字符串 class Solution { public:void getNext(vector<int> &next,const string s){int j0;next[j]0;for(int i1;i<s.size();i){while(j-1>0&&s[i]!s[j]){jnext[j-1];}if(s[i]s[j]){j;next[i]j;}else{next[i]0;}}}bool repeatedSubstringPa…...

3分钟上手Hysteria2:从安装到连接的超简单教程

3分钟上手Hysteria2&#xff1a;从安装到连接的超简单教程 Hysteria2是一款高效的网络加速工具&#xff0c;通过一键安装脚本即可快速部署&#xff0c;特别适合新手用户。本教程将带你在3分钟内完成从安装到连接的全过程&#xff0c;让你轻松享受高速网络体验。 准备工作&#…...

kprobe函数入口时的汇编跳板执行流程与栈帧机制

kprobe函数入口汇编跳板执行流程与栈帧机制 文章目录kprobe函数入口汇编跳板执行流程与栈帧机制前言环境准备ftrace跳板创建跳板执行流程与栈帧逐行拆解初始状态与安全校验双层栈帧构建&#xff08;CONFIG_FRAME_POINTER&#xff09;通用寄存器保存与C函数参数准备剩余寄存器保…...

C++的std--ranges适配器视图迭代器失效规则与悬垂引用

C的std::ranges适配器视图迭代器失效规则与悬垂引用 现代C引入了std::ranges库&#xff0c;为算法和范围操作提供了更强大的支持。使用适配器视图时&#xff0c;迭代器失效和悬垂引用问题可能成为隐藏的陷阱。理解这些规则对编写安全高效的代码至关重要。 视图的惰性求值特性…...

全方位解析GBFR Logs:《碧蓝幻想:Relink》战斗数据分析平台

全方位解析GBFR Logs&#xff1a;《碧蓝幻想&#xff1a;Relink》战斗数据分析平台 【免费下载链接】gbfr-logs GBFR Logs lets you track damage statistics with a nice overlay DPS meter for Granblue Fantasy: Relink. 项目地址: https://gitcode.com/gh_mirrors/gb/gbf…...

思源宋体完整使用指南:如何免费获得专业级中文字体解决方案

思源宋体完整使用指南&#xff1a;如何免费获得专业级中文字体解决方案 【免费下载链接】source-han-serif-ttf Source Han Serif TTF 项目地址: https://gitcode.com/gh_mirrors/so/source-han-serif-ttf 还记得上次为商业项目挑选字体时的头疼经历吗&#xff1f;看着那…...

Mi-Create:让小米穿戴设备拥有专属表盘的3步可视化设计法

Mi-Create&#xff1a;让小米穿戴设备拥有专属表盘的3步可视化设计法 【免费下载链接】Mi-Create Unofficial watchface creator for Xiaomi wearables ~2021 and above 项目地址: https://gitcode.com/gh_mirrors/mi/Mi-Create 你是否厌倦了小米手表上那些千篇一律的官…...