05-建造者模式-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. 当产品的构成部分需要动态变化时,可以使用建造者模式。

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.mzph.cn/news/190111.shtml

如若内容造成侵权/违法违规/事实不符,请联系多彩编程网进行投诉反馈email:809451989@qq.com,一经查实,立即删除!

相关文章

leetCode 494.递增子序列 + 回溯算法 + 图解 + 笔记

给你一个整数数组 nums &#xff0c;找出并返回所有该数组中不同的递增子序列&#xff0c;递增子序列中 至少有两个元素 。你可以按 任意顺序 返回答案。 数组中可能含有重复元素&#xff0c;如出现两个整数相等&#xff0c;也可以视作递增序列的一种特殊情况。 示例 1&#…

Python项目管理利器poetry我愿称之为神!

MongoDB是一种流行的NoSQL数据库&#xff0c;它以灵活的文档结构存储数据。MongoDB 提供了可用于 32 位和 64 位系统的预编译二进制包&#xff0c;你可以从MongoDB官网下载安装&#xff0c;MongoDB 预编译二进制包下载地址&#xff1a; https://www.mongodb.com/try/download/…

【Linux】信号概念和信号的产生

文章目录 一、什么是信号&#xff1f;1.signal系统调用2.从硬件解析键盘数据如何输入给内核3.同步和异步 二、信号的产生1.键盘组合键2. kill命令3.系统调用接口3.1kill3.2 raise3.3abort 4.异常5.软件条件 重谈core dump标志位 一、什么是信号&#xff1f; 以日常为例&#x…

Echarts 扇形百分比算法(最大余额法)

主要用于计算一个数组中某个值占总和的百分比&#xff0c;并且保留指定的小数位数 function getPercentValue(arrList, index, precision) { // arrList要计算数据的数组 // index要计算数组中值的下表 // precision百分比保留几位小数&#xff0c;默认保留2位小数 // 判断是否…

Elasticsearch:么是向量嵌入?

向量嵌入定义 向量嵌入 (vector embeddings) 是一种将单词、句子和其他数据转换为捕获其含义和关系的数字的方法。 它们将不同的数据类型表示为多维空间中的点&#xff0c;其中相似的数据点更紧密地聚集在一起。 这些数字表示可以帮助机器更有效地理解和处理这些数据。 单词和…

VS安装QT VS Tools编译无法通过

场景&#xff1a; 项目拷贝到虚拟机内部后&#xff0c;配置好相关环境后无法编译&#xff0c;安装QT VS Tools后依旧无法编译&#xff0c;查找资料网上说的是QT工具版本不一致导致的&#xff0c;但反复试了几个版本后依旧无法编译通过。错误信息如下&#xff1a; C:\Users\Ad…

OpenTelemetry系列 - 第1篇 相关概念

目录 一、背景二、概念2.1 Traces & Span2.2 Metrics2.3 Logs2.4 Baggage2.5 OTel2.6 OTLP2.7 Resources2.8 Instrumentation Scope2.9 Sampling 三、核心组件 一、背景 OpenTelemetry是一个可观察性框架和工具包&#xff0c;旨在创建和管理遥测数据&#xff0c;如跟踪、指…

Monocle 3 | 太牛了!单细胞必学R包!~(五)(差异分析之聚类比较与模块鉴定)

1写在前面 准备出去玩耍了&#xff0c;今天就不废话了&#xff0c;直接上主题吧。&#x1f973; monocle3做差异分析也是牛的一米&#xff01;~&#x1f33e; 2用到的包 rm(list ls())library(tidyverse)library(monocle3) 3示例数据 我们还是载入之前用过的一个数据集吧。&am…

Python 爬虫 一切都可爬,我爬我爬我还爬。你想要啥数据,来找我呀!

1. 什么是Python爬虫&#xff1f; Python爬虫是一种自动化程序&#xff0c;可以从互联网上获取信息并提取数据。通过模拟网页浏览器的行为&#xff0c;爬虫可以访问网页、抓取数据、解析内容&#xff0c;并将其保存到本地或用于进一步分析 2. 爬虫的合法性问题 使用Python爬虫…

Rust语言入门教程(十二) - 枚举类型Enums与模式匹配

枚举类型与模式匹配 欢迎使用并贡献我的开源webhook工具: https://github.com/owenchenxy/rusthook/什么是枚举类型 在Rust中, 枚举(Enums)类型更接近Haskell中的代数数据类型,而不是类似于C语言中的枚举类型。 定义一个枚举类型的步骤如下: 以enum关键字开头;后面紧接该…

HarmonyOs 4 (三) ArkTS语言

目录 一 认识ArkTs语言1.1 ArkTs1.2 基本结构 二 基本语法2.1 声明式UI2.1.1 创建组件2.1.1.1 无参数2.1.1.2 有参数2.1.1.3 组件样式2.1.1.4 组件方法2.1.1.5 组件嵌套 2.1.2 自定义组件2.1.2.1 基本结构2.1.2.2 成员函数/变量2.1.2.3 自定义组件的参数规定2.1.2.4 Build函数2…

高效转码工具Compressor for Mac,让视频处理更轻松

在现如今的数字时代&#xff0c;视频内容已经成为人们生活中不可或缺的一部分。无论是在社交媒体上分享生活点滴&#xff0c;还是在工作中制作专业的营销视频&#xff0c;我们都希望能够以高质量、高效率地处理和传输视频文件。而Compressor for Mac作为一款强大的视频转码工具…

vivado实现分析与收敛技巧6-策略建议

典型时序收敛策略需运行大量实现策略并选取其中最佳的策略以供在实验室内应用。 ML 策略同样可选 &#xff0c; 且只需您运行3 项策略即可达成类似的 QoR 收益。这些策略使用机器学习来检验布线后设计的各项功能特性 &#xff0c; 以便预测相同设计上不同策略的性能。在 repo…

C#获取字符串变量内存地址

在C#中&#xff0c;由于其设计原则&#xff0c;你不能直接获取字符串变量的内存地址。这是因为C#是一种安全的语言&#xff0c;不允许直接访问内存。这是为了预防程序员在处理内存时可能出现的错误&#xff0c;如越界访问&#xff0c;悬挂指针等。 但是&#xff0c;使用System.…

unity3d c#代码变更文本颜色,可选多参数,委托invoke延迟调用函数

[SerializeField] private Text warning; Color color ;warningOpen("注册成功", closeTime: 1.5f);warningOpen("登录成功", "green", 1.5f);public void warningOpen( string warn, string tmp"red", float closeTime5f ){warnin…

常用装备生产ERP有哪几种?有哪些作用

装备生产业务涉及原材料采购、车间排产、班组生产评估、派工单、接单报价、委外发料、库存盘点、设备台账、图纸设计等诸多环节&#xff0c;而各环节数据的共享问题普遍存在于装备生产企业内部&#xff0c;同时也直接影响企业的生产效率和整体效益等。 企业外部环境的变化和行…

【JavaScript手撕代码】防抖节流

防抖节流设计到的知识点很多&#xff0c;有闭包有修改this指向&#xff0c;应当作为重点记忆 防抖节流 防抖 防抖是指&#xff0c;短时间频繁触发fn&#xff0c;只执行最后一次&#xff0c;这样可以有效提高性能&#xff0c;减少服务器压力 也可以这样表述&#xff1a;函数…

Arduino驱动MCP9808数字温湿度传感器(温湿度传感器)

目录 1、传感器特性 2、硬件原理图 3、控制器和传感器连线图 4、驱动程序 <

探索意义的深度:自然语言处理中的语义相似性

一、说明 语义相似度&#xff0c;反应出计算机对相同内容&#xff0c;不同表达的识别能力。因而识别范围至少是个句子&#xff0c;最大范围就是文章&#xff0c;其研究方法有所区别。本文将按照目前高手的研究成绩&#xff0c;作为谈资介绍给诸位。 二、语义相似度简介 自然语言…

特种电源模块怎么测试?用电源模块测试系统测试需要哪些流程?

什么是特种电源? 特种电源即特殊种类的电源&#xff0c;是能够为各种特殊场合或应用提供稳定、可靠电力的电源设备。特种电源的特殊性主要体现在输出电压特别高&#xff0c;输出电流特别大&#xff0c;对稳定度、动态响应及纹波要求特别高等。 根据应用场景和功能&#xff0c;…