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

news2025/7/27 19:32:18

作者:翟天保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:
	// 装配CPU
	virtual void addCPU() = 0;
	// 装配GPU
	virtual 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:
	// 装配CPU
	virtual void addCPU() {
		m_computer.setCPU("Intel 酷睿i7-8700K");
	}
	// 装配GPU
	virtual 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:
	// 装配CPU
	virtual void addCPU() {
		m_computer.setCPU("Intel 酷睿i5-6300HQ");
	}
	// 装配GPU
	virtual 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;
}

       程序结果如下。

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

三、总结

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

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

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

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

相关文章

【GANs】什么是饱和损失函数 Non-Saturating LossFunction

Saturating VS Non-Saturating Loss functions in GANs【GANs】什么是饱和损失函数 Non-Saturating LossFunctionSaturating VS Non-Saturating Loss functions in GANs 饱和Loss 普通GAN loss是生成器希望最小化被判断为假的概率。x取值范围是[0,1]&#xff0c;所以图中函数…

一篇五分生信临床模型预测文章代码复现——FIgure 9.列线图构建,ROC分析,DCA分析 (五)

之前讲过临床模型预测的专栏,但那只是基础版本,下面我们以自噬相关基因为例子,模仿一篇五分文章,将图和代码复现出来,学会本专栏课程,可以具备发一篇五分左右文章的水平: 本专栏目录如下: Figure 1:差异表达基因及预后基因筛选(图片仅供参考) Figure 2. 生存分析,…

酷开系统AI人工智能技术,为营销抢夺更多目标消费者

随着越来越多的年轻群体回归家庭&#xff0c;互联网电视产业正在时代的浪潮下快速发展&#xff0c;如今已经有数以万计的家庭消费者倾向于在客厅场景中使用大屏电视观看更多丰富的电视节目&#xff0c;而这一趋势&#xff0c;对于急需线上互动营销渠道的企业和品牌方来说&#…

论文阅读笔记——《室内服务机器人的实时场景分割算法》

一、主要工作 通过深度可分离卷积、膨胀卷积和通道注意力机制设计轻量级的高准确度特征提取模块。融合浅层特征与深层语义特征获得更丰富的图像特征。在NYUDv2和CamVid数据集上的MIoU分别达到72.7%和59.9%&#xff0c;模型的计算力为4.2GFLOPs&#xff0c;参数量为8.3Mb。 二…

Hugging face 模型微调学习:T5-base的微调

最近想做一点文本生成的小实验&#xff0c;无意发现了NLPer应该了解到了一个网站&#xff1a;Hugging face。 Hugging face 在 github上开源了一个Transformers库&#xff0c;允许用户上传和下载的预训练的模型&#xff0c;并进行原有模型的基础上进行微调。如此&#xff0c;使…

【软件测试】web自动化测试如何开展合适?自动化测试用例如何设计?资深测试的总结......

目录&#xff1a;导读前言一、Python编程入门到精通二、接口自动化项目实战三、Web自动化项目实战四、App自动化项目实战五、一线大厂简历六、测试开发DevOps体系七、常用自动化测试工具八、JMeter性能测试九、总结&#xff08;尾部小惊喜&#xff09;前言 首先&#xff0c;还…

RK3588通用布线设计指南

&#xff08;1&#xff09;走线长度应包含过孔和封装。&#xff08;2&#xff09;由于表贴器件的焊盘会导致阻抗降低&#xff0c;为减小阻抗突变的影响&#xff0c;建议在表贴焊盘的正下方按焊盘大小挖去一层参考层。常用的表贴器件有&#xff1a;电容、 ESD、共模抑制电感、连…

docker部署gitlab过程中遇到的一些问题记录

文章目录用nginx代理docker部署的gitlab服务密码重置docker0网卡异常离线安装apt的包用nginx代理docker部署的gitlab服务 一般咱们不会去暴露很多端口给外面&#xff0c;所以部署完gitlab后&#xff0c;我希望能够用nginx来代理我们的gitlab服务。 gitlab的docker部署参考这个…

手把手教你使用vite打包自己的js代码包并推送到npm

准备 要有npm账号&#xff0c;没有的铁子去npm官网注册一个&#xff0c;又不要钱。 使用vite创建项目 一行代码搞定 npm create vite viet-demo框架选择Others 模板选择library 选择ts 这样项目就创建完了 这个项目默认有一个函数&#xff0c;用来记录按钮的点击次数并…

TCP协议和TCP连接

TCP协议和TCP连接一、TCP协议的简介二、TCP连接的简介1、TCP连接的建立&#xff08;TCP三次握手&#xff09;2、TCP连接的断开&#xff08;TCP四次挥手&#xff09;一、TCP协议的简介 TCP&#xff08;Transmission Control Protocol&#xff09;传输控制协议是一种面向连接的、…

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

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

opencv图像的算术运算

大家好&#xff0c;我是csdn的博主&#xff1a;lqj_本人 这是我的个人博客主页&#xff1a; lqj_本人的博客_CSDN博客-微信小程序,前端,python领域博主lqj_本人擅长微信小程序,前端,python,等方面的知识https://blog.csdn.net/lbcyllqj?spm1011.2415.3001.5343哔哩哔哩欢迎关注…

chatgpt如何解决模型训练过程中一些未知错误:以xgboot devices_.IsEmpty为例

本文尝试用现在最火的chatGPT在工作中提高生产力。具体背景如下&#xff1a;在训练模型过程中&#xff0c;为了避免资源抢占&#xff0c;我指定了其他的gpu来提高模型训练效率&#xff0c;但是发现训练的时候模型正常&#xff0c;但是在模型预测的时候一直报错&#xff0c;尝试…

opencv图像融合

大家好&#xff0c;我是csdn的博主&#xff1a;lqj_本人 这是我的个人博客主页&#xff1a; lqj_本人的博客_CSDN博客-微信小程序,前端,python领域博主lqj_本人擅长微信小程序,前端,python,等方面的知识https://blog.csdn.net/lbcyllqj?spm1011.2415.3001.5343哔哩哔哩欢迎关注…

代码随想录算法训练营第三十九天 | 62.不同路径,63. 不同路径 II

一、参考资料不同路径https://programmercarl.com/0062.%E4%B8%8D%E5%90%8C%E8%B7%AF%E5%BE%84.html 视频讲解&#xff1a;https://www.bilibili.com/video/BV1ve4y1x7Eu不同路径 IIhttps://programmercarl.com/0063.%E4%B8%8D%E5%90%8C%E8%B7%AF%E5%BE%84II.htmlhttps://progr…

Linux->父子进程初识和进程状态

目录 前言&#xff1a; 1. 父子进程创建 2. 进程状态 R(running)状态&#xff1a; S(sleep)状态&#xff1a; D(disk sleep)状态&#xff1a; T(stopped)状态&#xff1a; X(dead)和Z(zombie)状态&#xff1a; 孤儿进程&#xff1a; 前言&#xff1a; 本篇主要讲解关…

Python学习-----模块4.0(json字符串与json模块)

目录 1.json简介&#xff1a; 2.json对象 3.json模块 &#xff08;1&#xff09;json.dumps() 函数 &#xff08;2&#xff09;json.dumps() 函数 &#xff08;3&#xff09;json.loads() 函数 (4) json.load() 函数 4.总结&#xff1a; 1.json简介&#xff1a; SON(…

Mybatis之一级缓存二级缓存

介绍 缓存&#xff0c;就是将经常访问的数据&#xff0c;放到内存中&#xff0c;减少对数据库的访问&#xff0c;提高查询速度。Mybatis中也有缓存的概念&#xff0c;分为一级缓存和二级缓存。 一级缓存 一级缓存是Mybatis中SqlSession对象的缓存。当我们执行查询以后&#x…

C语言-结构体对齐

详细说明参考博客 (1条消息) C语言结构体对齐&#xff0c;超详细&#xff0c;超易懂_haozigegie的博客-CSDN博客 (1条消息) #pragma pack详解_OuJiang2021的博客-CSDN博客_#pragma pack 以下个人理解总结 出现结构体对齐考虑的根本原因就是&#xff1a;【数据存取执行效率】…

玫瑰花变蚊子血,自动化无痕浏览器对比测试,新贵PlayWright Vs 老牌Selenium,基于Python3.10

也许每一个男子全都有过这样的两个女人&#xff0c;至少两个。娶了红玫瑰&#xff0c;久而久之&#xff0c;红的变了墙上的一抹蚊子血&#xff0c;白的还是床前明月光&#xff1b;娶了白玫瑰&#xff0c;白的便是衣服上沾的一粒饭黏子&#xff0c;红的却是心口上一颗朱砂痣。–…