建造者模式(大话设计模式)C/C++版本

建造者模式

在这里插入图片描述

C++

参考:https://www.cnblogs.com/Galesaur-wcy/p/15907863.html

#include <iostream>
#include <vector>
#include <algorithm>
#include <string>
using namespace std;// Product Class,产品类,由多个部件组成。
class Product
{
private:vector<string> parts;public:// 添加产品部件void Add(string part){parts.push_back(part);}// 显示所有的产品部件void Show(){std::cout << "产品  创建" << std::endl;for_each(parts.cbegin(), parts.cend(), [](const string &s){ cout << s << " "; });cout << endl;}
};// Builder,抽象建造者,并声明一个得到产品建造后结果的方法GetResult。
class Builder
{
public:virtual ~Builder() = default;virtual void BuildPartA() = 0;virtual void BuildPartB() = 0;virtual Product *GetResult() = 0;
};// ConcreteBuilder1,具体建造者类,实现Builder接口中的具体方法。
class ConcreteBuilder1 : public Builder
{
private:Product *product = new Product;public:void BuildPartA() override{product->Add("部件A");}void BuildPartB() override{product->Add("部件B");}Product *GetResult() override{return product;}
};// ConcreteBuilder2,具体建造者类,实现Builder接口中的具体方法。
class ConcreteBuilder2 : public Builder
{
private:Product *product = new Product;public:void BuildPartA() override{product->Add("部件X");}void BuildPartB() override{product->Add("部件Y");}Product *GetResult() override{return product;}
};class Director //  指挥者类,指挥建造Product的过程(控制构建各部分组件的顺序)。
{
public:void Construct(Builder *const b){b->BuildPartA();b->BuildPartB();}
};int main()
{// 用户并不需要知道具体的建造过程,只需指定建造 Product 具体类型。Director director;Builder *b1 = new ConcreteBuilder1;Builder *b2 = new ConcreteBuilder2;cout << "用ConcreteBuilder1的方法建造产品: " << endl;director.Construct(b1);Product *p1 = b1->GetResult();p1->Show();cout << endl;cout << "用ConcreteBuilder2的方法建造产品: " << endl;director.Construct(b2);Product *p2 = b2->GetResult();p2->Show();cout << endl;delete p2;delete p1;delete b1;delete b2;p2 = p1 = nullptr;b1 = b2 = nullptr;return 0;
}

C

#include <stdio.h>
#include <stdlib.h>
#include <string.h>// 产品部件
typedef struct Product
{char **parts;size_t parts_count;
} Product;// 构建者接口
typedef struct Builder
{void (*build_part_a)(Product *);void (*build_part_b)(Product *);Product *(*get_result)(void *);
} Builder;// 具体构建者基类,用于存储产品实例
typedef struct ConcreteBuilder
{Product product;
} ConcreteBuilder;// 导演类
typedef struct Director
{void (*construct)(struct Director *, Builder *, void *, Product **);
} Director;// 初始化产品
void init_product(Product *product)
{product->parts = NULL;product->parts_count = 0;
}// 释放产品
void free_product(Product *product)
{if (product->parts != NULL){int i;for (i = 0; i < product->parts_count; ++i){free(product->parts[i]);}free(product->parts);}
}// 添加部件到产品
void add_part(Product *product, const char *part)
{product->parts = (char **)realloc(product->parts, sizeof(char *) * (product->parts_count + 1));product->parts[product->parts_count++] = strdup(part);
}// 展示产品部件
void show_product(Product *product)
{printf("产品    创建:\n");int i;for (i = 0; i < product->parts_count; ++i){printf("%s ", product->parts[i]);}printf("\n");
}// 实现ConcreteBuilder1的构建方法
void build_part_a_concrete_builder1(Product *product)
{add_part(product, "部件A");
}void build_part_b_concrete_builder1(Product *product)
{add_part(product, "部件B");
}// 实现ConcreteBuilder2的构建方法
void build_part_a_concrete_builder2(Product *product)
{add_part(product, "部件X");
}void build_part_b_concrete_builder2(Product *product)
{add_part(product, "部件Y");
}// 获取结果的通用实现,确保安全返回产品实例
Product *get_result_common(void *builder_void_ptr)
{ConcreteBuilder *builder = (ConcreteBuilder *)builder_void_ptr;return &builder->product;
}// 导演类构建方法
void construct(Director *director, Builder *builder, void *builder_void_ptr, Product **result)
{builder->build_part_a((Product *)builder_void_ptr);builder->build_part_b((Product *)builder_void_ptr);*result = builder->get_result(builder_void_ptr);
}int main()
{// 初始化DirectorDirector director = {.construct = construct};// 初始化ConcreteBuilder实例ConcreteBuilder builder1;init_product(&builder1.product);Builder b1 = {.build_part_a = build_part_a_concrete_builder1,.build_part_b = build_part_b_concrete_builder1,.get_result = get_result_common};ConcreteBuilder builder2;init_product(&builder2.product);Builder b2 = {.build_part_a = build_part_a_concrete_builder2,.build_part_b = build_part_b_concrete_builder2,.get_result = get_result_common};Product *p1 = NULL;Product *p2 = NULL;printf("使用ConcreteBuilder1的方法建造产品: \n");director.construct(&director, &b1, &builder1, &p1);show_product(p1);puts("");printf("使用ConcreteBuilder2的方法建造产品: \n");director.construct(&director, &b2, &builder2, &p2);show_product(p2);puts("");free_product(p1);free_product(p2);return 0;
}

总结

  1. 创建者模式是在当创建复杂对象的算法应该独立于该对象的组成部分以及他们的装配方式时适用的模式;
  2. 使得建造代码与表示代码分离,隐藏了该产品是如何组装的,多疑若需要改变一个产品的内部表示,只需要再定义一个具体的建造者就可以了

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

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

相关文章

荒野大镖客2启动找不到emp.dll的7个修复方法,轻松解决dll丢失的办法

一、emp.dll文件丢失的常见原因 安装或更新问题&#xff1a;在软件或游戏的安装过程中&#xff0c;可能由于安装程序未能正确复制文件到目标目录&#xff0c;或在更新过程中文件被意外覆盖或删除&#xff0c;导致emp.dll文件丢失。 安全软件误删&#xff1a;某些安全软件可能…

【ajax基础01】ajax简介

目录 一&#xff1a;ajax简介 1 什么是ajax 二&#xff1a;ajax使用 1 如何使用ajax 2 axios使用&#xff08;重点&#xff09; 三&#xff1a;案例 四&#xff1a;如何赚钱 一&#xff1a;ajax简介 1 什么是ajax AJAX&#xff08;Asynchronous JavaScript And XML &am…

莱辅络Rebro BIM机电专业软件

莱辅洛&#xff08;Rebro&#xff09;是一款专业机电 BIM 软件。它具备专业人士所期待的各种专业功能&#xff0c;应用于建筑机电工程的三维设计&#xff0c;并且适用于建筑、结构、给排水、暖通、电气五大专业。 该软件具有以下特点&#xff1a; • 3D 模型&#xff1a;可以…

渗透测试-若依框架的杀猪交易所系统管理后台

前言 这次是带着摸鱼的情况下简单的写一篇文章&#xff0c;由于我喜欢探究黑灰产业&#xff0c;所以偶尔机遇下找到了一个加密H币的交易所S猪盘&#xff0c;我记得印象是上年的时候就打过这一个同样的站&#xff0c;然后我是通过指纹查找其它的一些站&#xff0c;那个站已经关…

计网重点面试题-TCP三次握手四次挥手

三次握手 第一次握手(syn1) 客户端会随机初始化序号&#xff08;client_isn&#xff09;&#xff0c;将此序号置于 TCP 首部的「序列号」字段中&#xff0c;同时把 SYN 标志位置为 1&#xff0c;表示 SYN 报文。接着把第一个 SYN 报文发送给服务端&#xff0c;表示向服务端发…

一个电商创业者眼中的618:平台大变局

战役结束了&#xff0c;战斗还在继续。 一位朋友去年5月创业&#xff0c;网上卖咖啡&#xff0c;这个赛道很拥挤&#xff0c;时机也不好&#xff0c;今年是他参加第一个618。朋友说&#xff0c;今年的目标是锤炼团队&#xff0c;总结方法&#xff0c;以及最重要的——活下去。…

基于CentOS Stream 9平台 安装/卸载 Redis7.0.15

已更正systemctl管理Redis服务问题 1. 官方下载地址 https://redis.io/downloads/#redis-downloads 1.1 下载或上传到/opt/coisini目录下&#xff1a; mkdir /opt/coisini cd /opt/coisini wget https://download.redis.io/releases/redis-7.0.15.tar.gz2. 解压 tar -zxvf re…

基于IDEA的Maven简单工程创建及结构分析

目录 一、用 mvn 命令创建项目 二、用 IDEA 的方式来创建 Maven 项目。 &#xff08;1&#xff09;首先在 IDEA 下的 Maven 配置要已经确保完成。 &#xff08;2&#xff09;第二步去 new 一个 project &#xff08;创建一个新工程&#xff09; &#xff08;3&#xff09;…

1027. 方格取数

Powered by:NEFU AB-IN Link 文章目录 1027. 方格取数题意思路代码 1027. 方格取数 题意 某人从图中的左上角 A 出发&#xff0c;可以向下行走&#xff0c;也可以向右行走&#xff0c;直到到达右下角的 B 点。 在走过的路上&#xff0c;他可以取走方格中的数&#xff08;取…

Docker网络介绍

网络是虚拟化技术中最复杂的部分&#xff0c;也是Docker应用中的一个重要环节。 Docker中的网络主要解决容器与容器、容器与外部网络、外部网络与容器之间的互相通信的问题。 这些复杂情况的存在要求Docker有一个强大的网络功能去保障其网络的稳健性。因此&#xff0c;Docker…

SCI一区TOP|双曲正弦余弦优化算法(SCHO)原理及实现【免费获取Matlab代码】

目录 1.背景2.算法原理2.1算法思想2.2算法过程 3.结果展示4.参考文献5.代码获取 1.背景 2023年&#xff0c;J Bai受到双曲正弦余弦函数启发&#xff0c;提出了双曲正弦余弦优化算法&#xff08;Sinh Cosh optimizer, SCHO&#xff09;。 2.算法原理 2.1算法思想 SCHO灵感来源…

分布式锁(Redission)

分布式锁&#xff1a; 使用场景&#xff1a; 通常对于一些使用率高的服务&#xff0c;我们会进行多次部署&#xff0c;可能会部署在不同的服务器上&#xff0c;但是他们获取和操作的数据仍然是同一份。为了保证服务的强一致性&#xff0c;我们需要对线程进行加锁&#xff0c;…

ROS中的TF是什么

在ROS (Robot Operating System) 中&#xff0c;tf::TransformBroadcaster 是一个用于发布坐标变换信息的重要类&#xff0c;尤其在处理机器人定位和导航数据时非常常见。tf::TransformBroadcaster 对象允许你广播从一个坐标系到另一个坐标系的变换关系&#xff0c;这对于多传感…

Vue38 安装脚手架 vue-cli ,并使用脚手架创建项目

安装脚手架 vue-cli &#xff0c;并使用脚手架创建项目 第一步 安装脚手架 npm config set registry https:\\[registry.npmmirror.com // 切换淘宝镜像 npm install -g vue/cli第二步 切换到创建项目的目录&#xff0c;创建项目 cd XXX vue create XXX第三步 启动项目 npm…

【Linux】基础IO_3

文章目录 六、基础I/O3. 软硬链接4. 动静态库 未完待续 六、基础I/O 3. 软硬链接 使用 ln 就可以创建链接&#xff0c;使用 ln -s 可以创建软链接&#xff0c;直接使用 ln 则是硬链接。 我们对硬链接进行测试一下&#xff1a; 根据测试&#xff0c;我们知道了 硬链接就像一…

WPF文本绑定显示格式StringFormat设置-数值类型处理

绑定显示格式设置 在Textblock等文本控件中&#xff0c;我们经常要绑定一些数据类型&#xff0c;但是我们希望显示的时候能够按照我们想要的格式去显示&#xff0c;比如增加文本前缀&#xff0c;后面加单位&#xff0c;显示百分号等等&#xff0c;这种就需要对绑定格式进行处理…

天马学航——智慧教务系统(移动端)开发日志四

天马学航——智慧教务系统(移动端)开发日志四 日志摘要&#xff1a;优化了教师端界面的UI&#xff0c;更新了教师端添加课程&#xff0c;提交成绩等功能&#xff0c;修复了一些已知的BUG 1、教师添加课程设计 教师在此界面添加课程&#xff0c;并将数据提交后端进行审核 界…

Dell戴尔灵越Inspiron 16 Plus 7640/7630笔记本电脑原装Windows11下载,恢复出厂开箱状态预装OEM系统

灵越16P-7630系统包: 链接&#xff1a;https://pan.baidu.com/s/1Rve5_PF1VO8kAKnAQwP22g?pwdjyqq 提取码&#xff1a;jyqq 灵越16P-7640系统包: 链接&#xff1a;https://pan.baidu.com/s/1B8LeIEKM8IF1xbpMVjy3qg?pwdy9qj 提取码&#xff1a;y9qj 戴尔原装WIN11系…

python flask配置邮箱发送功能,使用flask_mail模块

&#x1f308;所属专栏&#xff1a;【Flask】✨作者主页&#xff1a; Mr.Zwq✔️个人简介&#xff1a;一个正在努力学技术的Python领域创作者&#xff0c;擅长爬虫&#xff0c;逆向&#xff0c;全栈方向&#xff0c;专注基础和实战分享&#xff0c;欢迎咨询&#xff01; 您的点…

Mamba: Linear-Time Sequence Modeling with Selective State Spaces论文笔记

文章目录 Mamba: Linear-Time Sequence Modeling with Selective State Spaces摘要引言 相关工作(SSMs)离散化计算线性时间不变性(LTI)结构和尺寸一般状态空间模型SSMs架构S4(补充)离散数据的连续化: 基于零阶保持技术做连续化并采样循环结构表示: 方便快速推理卷积结构表示: 方…