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

设计模式之建造者模式(C++)

作者:翟天保Steven
版权声明:著作权归作者所有,商业转载请联系作者获得授权,非商业转载请注明出处

一、建造者模式是什么?

       建造者模式是一种创建型的软件设计模式,用于构造相对复杂的对象。

       建造者模式可以将复杂对象的构建与它的表示分离,使得相同的构建过程可以得到不同的表示。如果说工厂模式和抽象工厂模式更注重产品整体,那建造者模式则更在乎产品的组成和细节。

       建造者模式的优点:

  1. 封装性好。有效地封装了建造过程(主要业务逻辑),使得系统整体的稳定性得到了一定保证。
  2. 解耦。产品本身和建造过程解耦,相同的建造过程可以创建出不同的产品。
  3. 产品建造过程精细化。该模式注重产品创建的整个过程,将复杂的步骤拆解得到多个相对简单的步骤,使得系统流程更清晰,且对细节的把控更精准。
  4. 易于扩展。如果有新产品需求,只需要添加一个建造者类即可,不需要改动之前的代码,符合开闭原则。

      建造者模式的缺点:

  1. 产品的组成部分和构建过程要一致,限制了产品的多样性。
  2. 若产品内部有结构上的变化,则整个系统都要进行大改,增加了后期维护成本。

二、建造者模式

2.1 结构图

       客户端即Main主函数,创建监督者,由监督者带领不同的建造者完成电脑产品的不同表示。

 

2.2 代码示例

       场景描述:我联系了一家外包公司,由他们的项目经理招人为我组建一批电脑,他先招了联想的团队,项目结束后;我想再弄一批对比下(甲方财大气粗),于是他们又招了惠普的团队,再次完成项目,非常不错。

//Product.h
/****************************************************/
#pragma once
#include <iostream>using namespace std;// 电脑产品类
class Computer
{
public:// 获取电脑信息void getComputer() {cout << "电脑产品配置为:" << endl;cout << " 处理器:" << getCPU() << endl;cout << " 显  卡:" << getGPU() << endl;cout << " 主  板:" << getMainBoard() << endl;cout << " 内存条:" << getRAM() << endl;}// 设置处理器void setCPU(string cpu){CPU = cpu;}// 设置显卡void setGPU(string gpu) {GPU = gpu;}// 设置主板void setMainBoard(string mb) {mainboard = mb;}// 设置内存条void setRAM(string ram) {RAM = ram;}// 获取处理器string getCPU() {return CPU;}// 获取显卡string getGPU() {return GPU;}// 获取主板string getMainBoard() {return mainboard;}// 获取内存条string getRAM() {return RAM;}private:string CPU;                             // 处理器string GPU;                             // 显卡string mainboard;                       // 主板string RAM;                             // 内存条
};
//Builder.h
/****************************************************/
#pragma once
#include <iostream>
#include "Product.h"using namespace std;// 抽象建造者
class Builder
{
public:// 装配CPUvirtual void addCPU() = 0;// 装配GPUvirtual void addGPU() = 0;// 装配主板virtual void addMainBoard() = 0;// 装配内存virtual void addRAM() = 0;// 获取电脑产品Computer getComputer() {return m_computer;}protected:Computer m_computer;                         // 电脑产品
};// 联想-建造者
class LenovoBuilder : public Builder
{
public:// 装配CPUvirtual void addCPU() {m_computer.setCPU("Intel 酷睿i7-8700K");}// 装配GPUvirtual void addGPU() {m_computer.setGPU("RTX 4050");}// 装配主板virtual void addMainBoard() {m_computer.setMainBoard("B760");}// 装配内存virtual void addRAM() {m_computer.setRAM("三星DDR4 2666mhz 16G");}
};// 惠普-建造者
class HPBuilder : public Builder
{
public:// 装配CPUvirtual void addCPU() {m_computer.setCPU("Intel 酷睿i5-6300HQ");}// 装配GPUvirtual void addGPU() {m_computer.setGPU("GTX 1060");}// 装配主板virtual void addMainBoard() {m_computer.setMainBoard("B660");}// 装配内存virtual void addRAM() {m_computer.setRAM("金士顿DDR4 2666mhz 16G");}
};
//Director.h
/****************************************************/
#pragma once
#include <iostream>
#include "Builder.h"using namespace std;// 监督者
class Director
{
public:// 构造函数Director(Builder* builder) {m_builder = builder;}// 析构函数~Director() {if (m_builder != nullptr)delete m_builder;}// 替换建造者void setBuilder(Builder *builder) {m_builder = builder;}// 建造Computer construct() {m_builder->addCPU();m_builder->addGPU();m_builder->addMainBoard();m_builder->addRAM();return m_builder->getComputer();}
private:Builder *m_builder;                     // 建造者
};
//main.cpp
/****************************************************/
#include <iostream>
#include <string>
#include "Director.h"using namespace std;int main()
{// 一号建造者-联想Builder *builder1 = new LenovoBuilder();cout << "联想建造者等待就业。" << endl;// 由监督者监督项目启动Director *director = new Director(builder1);cout << "监督者(项目经理)开始招人做项目。" << endl;// 联想项目完毕,获取联想电脑产品Computer computer1 = director->construct();cout << "联想项目结束。" << endl;computer1.getComputer();// 二号建造者-惠普Builder *builder2 = new HPBuilder();cout << "惠普建造者等待就业。" << endl;// 替换建造者director->setBuilder(builder2);cout << "监督者(项目经理)替换建造者,做新项目。" << endl;Computer computer2 = director->construct();cout << "惠普项目结束。" << endl;computer2.getComputer();return 0;
}

       程序结果如下。

        在上述示例中,我们可以看到,产品有相同的构建过程,但是不同的建造者却可以完成不同表示的产品,产品的结构类似,但具体内容各不相同。

三、总结

       我尽可能用较通俗的话语和直观的代码例程,来表述我对建造者模式的理解,或许有考虑不周到的地方,如果你有不同看法欢迎评论区交流!希望我举的例子能帮助你更好地理解建造者模式。

       如果文章帮助到你了,可以点个赞让我知道,我会很快乐~加油!

相关文章:

设计模式之建造者模式(C++)

作者&#xff1a;翟天保Steven 版权声明&#xff1a;著作权归作者所有&#xff0c;商业转载请联系作者获得授权&#xff0c;非商业转载请注明出处 一、建造者模式是什么&#xff1f; 建造者模式是一种创建型的软件设计模式&#xff0c;用于构造相对复杂的对象。 建造者模式可以…...

linux常见的系统日志

我们了解一下常见的系统日志&#xff0c;知道哪些需要收集 1. /var/log/boot.log linux中/var/log/boot.log是系统启动时的日志&#xff0c;其包括自启动服务。 2. /var/log/btmp linux中/var/log/btmp是记录登录失败信息的日志&#xff0c;是一种非文本文件&#xff0c;可以使…...

支付系统中的设计模式09:组合模式

现在就剩下怎么能够实现运营部提出的「打印出平台顾客购买的商品小票」这个需求了。 我们去超市买完东西之后,都会收到收银员打印出来的小票,就是商品清单、价格、数量和汇总的信息。下面这个我想应该99%的人都见过吧。 图三十七:超市购物小票 线上也是一样,也会有这种购物…...

Linux 文件权限之umask

目录一、文件默认创建权限二、文件默认创建权限掩码三、文件权限的修改本文主要讲解Linux中的文件默认创建权限相关的内容&#xff0c;涉及到的内容有&#xff1a;文件默认创建权限、文件默认创建权限掩码、文件访问权限的修改。 文件访问者共三类&#xff1a;文件所有者、文件…...

SAP ABAP 理解RAWSTRING(XSTRING) 类型

用F1查看的时候&#xff0c;这里是这样说的&#xff1a; The types RAWSTRING and STRING have a variable length. A maximum length for these types can be specified, but has no upper limit. The type SSTRING is available as of release 6.10 and it has a variable …...

Linux核心技能:2023主流监控Prometheus详解,附官方可复制中文文档教程

Prometheus既是一个时序数据库&#xff0c;又是一个监控系统&#xff0c;更是一套完备的监控生态解决方案。作为时序数据库&#xff0c;目前Prometheus已超越了老牌的时序数据库OpenTSDB、Graphite、RRDtool、KairosDB等&#xff0c;如图所示。 &#xff08;来源网络&#xff0…...

金山文档这样玩,效率「狂飙」

1985年&#xff0c;微软发布了第一代的Excel。现在&#xff0c;Excel成为了许多打工人的必备工具&#xff0c;却也在很多人的日常工作中&#xff0c;带来了海量跨表同步、大批数据对齐的日常繁琐工作&#xff0c;逐渐沦为“表哥”“表妹”。多维表&#xff0c;是新一代数据效率…...

【类与对象】封装对象的初始化及清理

C面向对象的三大特性&#xff1a;封装、继承、多态。具有相同性质的对象&#xff0c;抽象为类。 文章目录1 封装1.1 封装的意义&#xff08;一&#xff09;1.2 封装的意义&#xff08;二&#xff09;1.3 struct 和 class区别1.4 成员属性设置为私有练习案例&#xff1a;1 设计…...

【算法】——并查集

作者&#xff1a;指针不指南吗 专栏&#xff1a;算法篇 &#x1f43e;或许会很慢&#xff0c;但是不可以停下&#x1f43e; 文章目录1.思想2.模板3.应用3.1 合并集合3.2 连通块中点的数量1.思想 并查集是一种树型的数据结构&#xff0c;用于处理一些不相交集合的合并及查询问题…...

Python3,为了无损压缩gif动图,我不得不写了一个压缩神器,真香。

gif动图无损压缩1、引言2、代码实战2.1 模块介绍2.2 安装2.3 代码示例3、总结1、引言 小屌丝&#xff1a;鱼哥&#xff0c; 求助~ 求助~ 求助~ 小鱼&#xff1a;你这是告诉我&#xff0c;重要的事情 说三遍吗&#xff1f; 小屌丝&#xff1a;你可以这么理解。 小鱼&#xff1a…...

文献阅读 An implementation of the seismic resolution enhancing network based on GAN

题目 An implementation of the seismic resolution enhancing network based on GAN 基于GAN的地震分辨率增强网络的实现 摘要 对于地震数据&#xff0c;本文利用深度学习来学习不同层次的特征并将它们合并以恢复缺失的分辨率。 将GAN网络引入到地震数据处理&#xff1b;对…...

Google员工说出了我不敢说的心里话!

前言&#xff1a;本文来自Beyond的投稿&#xff0c;码农翻身做了修改。今天在Medium上看到一篇文章《The maze is in the mouse》&#xff0c;是一个刚从Google离职的员工写的&#xff0c;揭开了Google内部的各种问题&#xff0c;引发了很多人的共鸣&#xff0c;到目前为止&…...

“御黑行动”进行中,三月重保单位已开放接入!

三月重保在即&#xff0c;对于诸多政企单位来说&#xff0c;正面临着特殊时期的安全保障工作这一重要“大考”。 面对越来越专业且隐匿的攻击&#xff0c;各单位承受着巨大压力&#xff0c;尤其是政府、国企、央企等具有重要地位及广泛社会影响面的单位&#xff0c;其网站及业务…...

taobao.top.oaid.client.decrypt( 端侧OAID解密 )

&#xffe5;开放平台免费API不需用户授权 解码OAID(Open Addressee ID)&#xff0c;返回收件人信息。该接口用于客户端直接查看订单隐私数据&#xff0c;解密数据不经过ISV服务器&#xff0c;且包含风控等安全检测。 公共参数 请求地址: HTTP地址&#xff1a;http://gw.api.ta…...

QT+OpenGL鼠标操作和模型控制

文章目录QTOpenGL鼠标操作和模型控制鼠标拾取理论有点小复杂从鼠标计算射线第 0 步&#xff1a;2D 视口坐标第 1 步&#xff1a;3d归一化设备坐标第 2 步&#xff1a;4d齐次剪辑坐标第 3 步&#xff1a;4d眼(相机)坐标第 4 步&#xff1a;4d 世界坐标代码展示模型控制多模型加载…...

爱奇艺“资产重定价”:首次全年运营盈利是拐点,底层逻辑大改善

长视频行业历时一年有余的降本增效、去肥增瘦&#xff0c;迎来首个全周期圆满收官的玩家。 北京时间2月22日美股盘前&#xff0c;爱奇艺发布2022年Q4及全年财报&#xff0c;Q4 Non-GAAP净利润明显超越预期&#xff0c;且首次实现全年运营盈利。受业绩提振&#xff0c;爱奇艺盘…...

MySQL —— 库的操作

文章目录1. 创建数据库2. 字符集和校验规则3. 数据库的基本操作3.1 查看数据库3.2 显示创建数据库的语句3.3 修改数据库3.4 删除数据库3.5 备份&#xff0c;还原数据库4. 查看数据库的连接情况1. 创建数据库 基本语法&#xff1a; create database if not exists 数据库名 选项…...

修改shell的命令提示符

以下内容源于C语言中文网的学习与整理&#xff0c;非原创&#xff0c;如有侵权请告知删除。 一、命令提示符格式 从虚拟控制台登陆后&#xff0c;或者从桌面环境的终端进入shell后&#xff0c;就可以看见shell的命令提示符&#xff0c;这意味着可以输入命令了。注意&#xff…...

介绍并比较Apache Hive支持的文件格式

Apache Hive 支持几种熟知的Hadoop使用的文件格式&#xff0c;Hive也能加载并查询其他Hadoop组件创建的不同文件格式&#xff0c;如Pig或MapReduce。本文对比Hive不同文件格式&#xff0c;如&#xff1a;TextFile, SequenceFile, RCFile, AVRO, ORC,Parquet&#xff0c;Clouder…...

C语言之文件操作

目录 一、什么是文件&#xff1f; 二、C语言如何操作文件 1.操作方式 2.文件指针 2.1 定义文件指针 2.2文件的打开与关闭 2.3文件的顺序读写 2.3文件的随机读写 总结 一、什么是文件&#xff1f; 在电脑磁盘的上的文件。在程序设计中&#xff0c;分为两种&#xff1a;程序…...

centos 7 部署awstats 网站访问检测

一、基础环境准备&#xff08;两种安装方式都要做&#xff09; bash # 安装必要依赖 yum install -y httpd perl mod_perl perl-Time-HiRes perl-DateTime systemctl enable httpd # 设置 Apache 开机自启 systemctl start httpd # 启动 Apache二、安装 AWStats&#xff0…...

java调用dll出现unsatisfiedLinkError以及JNA和JNI的区别

UnsatisfiedLinkError 在对接硬件设备中&#xff0c;我们会遇到使用 java 调用 dll文件 的情况&#xff0c;此时大概率出现UnsatisfiedLinkError链接错误&#xff0c;原因可能有如下几种 类名错误包名错误方法名参数错误使用 JNI 协议调用&#xff0c;结果 dll 未实现 JNI 协…...

376. Wiggle Subsequence

376. Wiggle Subsequence 代码 class Solution { public:int wiggleMaxLength(vector<int>& nums) {int n nums.size();int res 1;int prediff 0;int curdiff 0;for(int i 0;i < n-1;i){curdiff nums[i1] - nums[i];if( (prediff > 0 && curdif…...

相机Camera日志分析之三十一:高通Camx HAL十种流程基础分析关键字汇总(后续持续更新中)

【关注我,后续持续新增专题博文,谢谢!!!】 上一篇我们讲了:有对最普通的场景进行各个日志注释讲解,但相机场景太多,日志差异也巨大。后面将展示各种场景下的日志。 通过notepad++打开场景下的日志,通过下列分类关键字搜索,即可清晰的分析不同场景的相机运行流程差异…...

【碎碎念】宝可梦 Mesh GO : 基于MESH网络的口袋妖怪 宝可梦GO游戏自组网系统

目录 游戏说明《宝可梦 Mesh GO》 —— 局域宝可梦探索Pokmon GO 类游戏核心理念应用场景Mesh 特性 宝可梦玩法融合设计游戏构想要素1. 地图探索&#xff08;基于物理空间 广播范围&#xff09;2. 野生宝可梦生成与广播3. 对战系统4. 道具与通信5. 延伸玩法 安全性设计 技术选…...

今日学习:Spring线程池|并发修改异常|链路丢失|登录续期|VIP过期策略|数值类缓存

文章目录 优雅版线程池ThreadPoolTaskExecutor和ThreadPoolTaskExecutor的装饰器并发修改异常并发修改异常简介实现机制设计原因及意义 使用线程池造成的链路丢失问题线程池导致的链路丢失问题发生原因 常见解决方法更好的解决方法设计精妙之处 登录续期登录续期常见实现方式特…...

学校时钟系统,标准考场时钟系统,AI亮相2025高考,赛思时钟系统为教育公平筑起“精准防线”

2025年#高考 将在近日拉开帷幕&#xff0c;#AI 监考一度冲上热搜。当AI深度融入高考&#xff0c;#时间同步 不再是辅助功能&#xff0c;而是决定AI监考系统成败的“生命线”。 AI亮相2025高考&#xff0c;40种异常行为0.5秒精准识别 2025年高考即将拉开帷幕&#xff0c;江西、…...

Kafka入门-生产者

生产者 生产者发送流程&#xff1a; 延迟时间为0ms时&#xff0c;也就意味着每当有数据就会直接发送 异步发送API 异步发送和同步发送的不同在于&#xff1a;异步发送不需要等待结果&#xff0c;同步发送必须等待结果才能进行下一步发送。 普通异步发送 首先导入所需的k…...

C# 表达式和运算符(求值顺序)

求值顺序 表达式可以由许多嵌套的子表达式构成。子表达式的求值顺序可以使表达式的最终值发生 变化。 例如&#xff0c;已知表达式3*52&#xff0c;依照子表达式的求值顺序&#xff0c;有两种可能的结果&#xff0c;如图9-3所示。 如果乘法先执行&#xff0c;结果是17。如果5…...

Golang——9、反射和文件操作

反射和文件操作 1、反射1.1、reflect.TypeOf()获取任意值的类型对象1.2、reflect.ValueOf()1.3、结构体反射 2、文件操作2.1、os.Open()打开文件2.2、方式一&#xff1a;使用Read()读取文件2.3、方式二&#xff1a;bufio读取文件2.4、方式三&#xff1a;os.ReadFile读取2.5、写…...