建造者模式-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/171615.shtml

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

相关文章

RabbitMQ之延迟消息实战

RabbitMQ之延迟消息实战 使用死信交换机实现延迟消息 使用死信交换机的过期时间以及没有消费者进行消费&#xff0c;时间到了就会到死信队列中&#xff0c;由此可以实现延迟消息使用延迟消息插件 前提&#xff1a;需要mq配置插件 延时信息案例实战 把一个30分钟的延迟消息可以…

前端review

关于实时预览vs code中的颜色代码需要安装的插件&#xff0c;包括html文件格式中的颜色代码安装Flutter Color插件 VSCode 前端常用插件集合 1.Auto Close Tag自动闭合HTML/XML标签 2.Auto Rename Tag自动完成另一侧标签的同步修改 3.Beautify格式化代码&#xff0c;值得注…

【高可用架构】Haproxy 和 Keepalived 的区别

Haproxy 和 Keepalived 的区别 1.负载均衡器介绍2.Haproxy 和 Keepalived 的基本概念和特点2.1 Haproxy2.2 Keepalived 3.Haproxy 和 Keepalived 的区别3.1 功能上的区别3.2 架构上的区别3.3 配置上的区别 4.总结 1.负载均衡器介绍 负载均衡器是一种解决高并发和高可用的常用的…

【开源】基于Vue和SpringBoot的农家乐订餐系统

项目编号&#xff1a; S 043 &#xff0c;文末获取源码。 \color{red}{项目编号&#xff1a;S043&#xff0c;文末获取源码。} 项目编号&#xff1a;S043&#xff0c;文末获取源码。 目录 一、摘要1.1 项目介绍1.2 项目录屏 二、功能模块2.1 用户2.2 管理员 三、系统展示四、核…

C/C++内存管理,malloc,realloc,calloc,new,delete详解!!!

1.初步了解内存中各个区间存储的数据特征 1.栈区&#xff1a;存储一些局部变量、函数参数、返回值等&#xff0c;跟函数栈振有关&#xff0c;出了作用域&#xff0c;生命周期结束。 2.堆区&#xff1a;用于动态开辟空间&#xff0c;如果不主动销毁空间&#xff0c;则程序运行结…

因式分解的几何意义

本来准备和女儿一起玩一道几何题&#xff0c;想想还是算了&#xff0c;不如讲点更有趣的。 任何因式分解都是在堆积木&#xff0c;不信你看&#xff1a; 二项式定理&#xff0c;洋灰三角&#xff0c;都是面积&#xff0c;体积&#xff0c;超维体积的拼接&#xff0c;一个大超…

Python 安装django-cors-headers解决跨域问题

一、PythonCorsHeaders概念 PythonCorsHeaders是一个轻量级的Python工具&#xff0c;用于解决跨域HTTP请求的问题。它允许你指定哪些网站或IP地址可以访问你的站点&#xff0c;并控制这些站点可以访问哪些内容。 现代网站越来越多地使用Ajax技术&#xff0c;使得浏览器能够从不…

【人工智能】Chatgpt的训练原理

前言 前不久&#xff0c;在学习C语言的我写了一段三子棋的代码&#xff0c;但是与我对抗的电脑是没有任何思考的&#xff0c;你看了这段代码就理解为什么了&#xff1a; void computerMove(char Board[ROW][COL], int row, int col) {while (1){unsigned int i rand() % ROW, …

设计模式之十二:复合模式

模式通常被一起使用&#xff0c;并被组合在同一个解决方案中。 复合模式在一个解决方案中结合两个或多个模式&#xff0c;以解决一般或重复发生的问题。 首先重新构建鸭子模拟器&#xff1a; package headfirst.designpatterns.combining.ducks;public interface Quackable …

【网络】传输层 --- 详解TCP协议

目录 一、协议段格式及其策略确认应答(ACK)机制6个标志位超时重传流量控制滑动窗口1、先谈滑动窗口一般情况2、再谈特殊窗口 拥塞控制拥塞窗口 延迟应答&&捎带应答面向字节流粘包问题 二、三次握手和四次挥手三次握手为什么是3次&#xff1f;不是2、4、5、6次呢 四次挥…

NoSQL基础知识小结

NoSQL 基础知识 什么是 NoSQL? NoSQL&#xff08;Not Only SQL 的缩写&#xff09;泛指非关系型的数据库&#xff0c;主要针对的是键值、文档以及图形类型数据存储。 NoSQL 数据库天生支持分布式&#xff0c;数据冗余和数据分片等特性&#xff0c;旨在提供可扩展的高可用高…

【代码】基于VMD(变分模态分解)-SSA(麻雀搜索算法优化)-LSTM的光伏功率预测模型(完美复现)matlab代码

程序名称&#xff1a;基于VMD&#xff08;变分模态分解&#xff09;-SSA&#xff08;麻雀搜索算法优化&#xff09;-LSTM的光伏功率预测模型 实现平台&#xff1a;matlab 代码简介&#xff1a;提出了变分模态分解(VMD)和麻雀搜索算法(SSA)与长短期记忆神经网络 (LSTM)相耦合,…

Spark-06:Spark 共享变量

目录 1.广播变量&#xff08;broadcast variables&#xff09; 2.累加器&#xff08;accumulators&#xff09; 在分布式计算中&#xff0c;当在集群的多个节点上并行运行函数时&#xff0c;默认情况下&#xff0c;每个任务都会获得函数中使用到的变量的一个副本。如果变量很…

Android 相机库CameraView源码解析 (一) : 预览

1. 前言 这段时间&#xff0c;在使用 natario1/CameraView 来实现带滤镜的预览、拍照、录像功能。 由于CameraView封装的比较到位&#xff0c;在项目前期&#xff0c;的确为我们节省了不少时间。 但随着项目持续深入&#xff0c;对于CameraView的使用进入深水区&#xff0c;逐…

【LeetCode】挑战100天 Day17(热题+面试经典150题)

【LeetCode】挑战100天 Day17&#xff08;热题面试经典150题&#xff09; 一、LeetCode介绍二、LeetCode 热题 HOT 100-192.1 题目2.2 题解 三、面试经典 150 题-193.1 题目3.2 题解 一、LeetCode介绍 LeetCode是一个在线编程网站&#xff0c;提供各种算法和数据结构的题目&…

[建议收藏] 一个网站集合所有最新最全的AI工具

今天给大家推荐一个宝藏的AI工具合集网站&#xff0c;有了这个网站&#xff0c;你们再也不用去其他地方找AI工具了。 名称&#xff1a;AI-BOT工具集 这个网站精选1000AI工具&#xff0c;并持续每天更新添加&#xff0c;包括AI写作、AI绘画、AI音视频处理、AI平面设计、AI自动编…

Atcoder Beginner Contest 330——A~F题

A - Counting Passes Description Problem Statement N N N people labeled 1 , 2 , … , N 1,2,\dots,N 1,2,…,N took an exam, and person i i i scored A i A_i Ai​ points. Only those who scored at least L L L points pass this exam. Determine how many peopl…

SpringBoot:邮件发送

官网文档&#xff1a;39. Sending Email (spring.io)。 Sending Email Spring框架提供了JavaMailSender实例&#xff0c;用于发送邮件。 如果SpringBoot项目中包含了相关的启动器&#xff0c;那么就会自动装配一个Bean实例到项目中。 在SpringBoot项目中引入如下Email启动器&a…

【数据分享】2019-2023年我国区县逐月新房房价数据(Excel/Shp格式)

房价是一个城市发展程度的重要体现&#xff0c;一个城市的房价越高通常代表这个城市越发达&#xff0c;对于人口的吸引力越大&#xff01;因此&#xff0c;房价数据是我们在各项城市研究中都非常常用的数据&#xff01;之前我们分享过2019-2023年我国地级市逐月房价数据&#x…

Spring Boot 项目中读取 YAML 文件中的数组、集合和 HashMap

在 Spring Boot 项目中&#xff0c;我们经常使用 YAML 文件来配置应用程序的属性。在这篇博客中&#xff0c;我将模拟如何在 Java 的 Spring Boot 项目中读取 YAML 文件中的数组、集合和 HashMap。 1. 介绍 YAML&#xff08;YAML Aint Markup Language&#xff09;是一种人类…