【16】c++设计模式——>建造者(生成器)模式

什么是建造者模式?

建造者模式(Builder Pattern)是一种创建型设计模式,它允许你构造复杂对象步骤分解。你可以不同的步骤中使用不同的方式创建对象,且对象的创建与表示是分离的。这样,同样的构建过程可以创建不同的表示。
在 C++ 中,建造者模式通常涉及到以下几个关键部分:
1.产品(Product):这是最终要构造的对象。它通常包含很多属性。
2.抽象建造者(Abstract Builder):这是一个接口,定义了创建产品所需的各个步骤的方法。
3.具体建造者(Concrete Builder):这是实现抽象建造者接口的具体类。它实现了创建产品所需的各个步骤。
4.导演(Director):这个类负责执行创建产品的整个过程。它使用具体建造者来创建产品的各个部分,并在适当的时候调用它们。

建造者模式和工厂模式的区别?

建造者模式和工厂模式都是创建型设计模式,但它们的关注点和用途有所不同。以下是它们的主要区别:
1.关注点建造者模式注重零部件的组装过程,而工厂方法模式更注重零部件的创建过程
2.创建对象的力度:建造者模式创建复杂的对象,由各种复杂的部件组成,而工厂模式创建出来的对象都一样。
3.顺序:建造者模式根据建造过程中的顺序不一样,最终的对象部件组成也不一样。而工厂模式则没有这样的关注。
4.使用场景:创建简单对象时,通常使用工厂模式;创建复杂对象时,可以考虑使用建造者模式。
总的来说,工厂模式更注重对象的创建,而建造者模式更注重对象的组装过程和组成部分。在实际应用中,可以根据需要选择使用哪种设计模式。

建造者模式适用什么场景,举个具体的例子

建造者模式适用于创建具有多个组成部分的复杂对象,尤其是那些需要对个步骤来创建的对象。
假设我们需要创建一个复杂的“电脑”对象,该对象包含多个组成部分,如“CPU”、“内存”、“硬盘”等。我们可以使用建造者模式来创建这个对象,具体步骤如下:
1.首先我们需要一个产品类Computer ,也就是电脑,这是最终要构造的对象,电脑通常包含很多属性也就是组成部分,比如CPU,内存,硬盘这些;例如,在具体电脑建造者中,我们可以调用“Computer”类的“setCPU()”、“setMemory()”和“setHardDisk()”方法来设置电脑的各个组成部分
2.然后,我们定义一个抽象建造者ComputerBuilder接口,该接口定义了创建电脑对象所需的各个步骤的虚方法。如“buildCPU()”、“buildMemory()”、“buildHardDisk()”等。
3.接下来,我们定义一个具体建造者ConcreteComputerBuilder类,该类实现了抽象建造者接口中定义的所有方法。在具体建造者中,我们可以按照需要的顺序和方式来创建电脑对象的各个组成部分。
4.然后,我们定义一个导演ComputerDirector类,该类负责执行创建电脑对象的整个过程。导演类中使用具体建造者来创建电脑对象的各个部分,并在适当的时候调用它们。
5.最后,客户端代码可以使用导演类来创建电脑对象。客户端不需要知道电脑对象内部的具体实现细节,只需要调用导演类提供的方法即可。
代码示例:

#include<iostream>
#include<string>
using namespace std;//1.产品:电脑
class Computer
{
public:void setCPU(string cpu) { m_cpu = cpu; }void setMemory(string memory) { m_memory = memory; }void setHardDisk(string hardDisk) { m_hardDisk = hardDisk; }//const位于函数参数列表之后,表示该函数是一个常量成员函数,该函数不会修改任何成员变量的值void print()const {   std::cout << "CPU: " << m_cpu << ", Memory: " << m_memory << ", Hard Disk: " << m_hardDisk << std::endl;}
private:string m_cpu;string m_memory;string m_hardDisk;
};
//2.抽象建造者:电脑建造者接口
class ComputerBuilder
{
public:virtual ~ComputerBuilder() {}; //虚析构,为了销毁父类指针所指向的子类对象virtual void buildCPU() = 0; virtual void buildMemory() = 0;virtual void buildHardDisk() = 0;virtual Computer* getComputer() = 0;
};
//3.具体建造者:具体的电脑建造者
class  ConcreteComputerBuilder :public ComputerBuilder
{
public:void buildCPU() { m_computer->setCPU("Intel Core i7"); }void buildMemory() { m_computer->setMemory("16GB DDR4");}void buildHardDisk() { m_computer->setHardDisk("1TB SSD");}Computer* getComputer() { return m_computer; }private:Computer* m_computer = new Computer;
};
//4.导演:电脑建造导演
class ComputerDirector
{
public:ComputerDirector(ComputerBuilder* builder) :m_builder(builder) {}void construct() {m_builder->buildCPU();m_builder->buildMemory();m_builder->buildHardDisk();}
private:ComputerBuilder* m_builder;
};
int main()
{ConcreteComputerBuilder builder;//创建一个具体的电脑对象ComputerDirector director(&builder); //创建一个导演director.construct();builder.getComputer()->print();delete builder.getComputer();return 0;
}

在这里插入图片描述

手机生产

我现在要生产iphone手机,有iPhone14和iPhone15,各自又有mini和pro两个版本。

#include <iostream>
#include <memory>//产品类:iphone
class iPhone
{
public:void setMemory(const std::string& memory) { m_memory = memory; }void setScreen(const std::string& screen) { m_screen = screen; }void setAppearance(const std::string& apperance) { m_appearance = apperance; }void showInfo() const {std::cout << "Memory: " << m_memory << std::endl;std::cout << "Screen: " << m_screen << std::endl;std::cout << "Appearance: " << m_appearance << std::endl;}
private:std::string m_memory;std::string m_screen;std::string m_appearance;
};
//抽象建造者:iphone手机建造者接口
class iPhoneBuilder
{
public:virtual void buildMemory() = 0;virtual void buildScreen() = 0;virtual void buildAppearance() = 0;virtual std::unique_ptr<iPhone> getiPhone() = 0;};
//具体建造者:iPhone14 Mini 建造者
class iPhoneBuilder14Mini :public iPhoneBuilder
{void buildMemory() { m_memory = "64GB"; }void buildScreen() { m_screen = "5.4-inch"; }void buildAppearance() { m_appearance = "Glass back and aluminum frame"; };std::unique_ptr<iPhone>  getiPhone() override{std::unique_ptr<iPhone> iphone = std::make_unique<iPhone>();iphone->setMemory(m_memory);iphone->setScreen(m_screen);iphone->setAppearance(m_appearance);return iphone;}private:std::string m_memory;std::string m_screen;std::string m_appearance;
};//具体建造者:iPhone14 pro 建造者
class iPhoneBuilder14PRO :public iPhoneBuilder
{void buildMemory() { m_memory = "256GB"; }void buildScreen() { m_screen = "6.1-inch"; }void buildAppearance() { m_appearance = "Ceramic back and stainless steel frame"; };std::unique_ptr<iPhone>  getiPhone() override{std::unique_ptr<iPhone> iphone = std::make_unique<iPhone>();iphone->setMemory(m_memory);iphone->setScreen(m_screen);iphone->setAppearance(m_appearance);return iphone;}
private:std::string m_memory;std::string m_screen;std::string m_appearance;
};//导演类:生成手机
class Director 
{
public:std::unique_ptr<iPhone> create(iPhoneBuilder& builder){builder.buildMemory();builder.buildScreen();builder.buildAppearance();return builder.getiPhone();}
};
int main()
{Director director;//iphone14 miniiPhoneBuilder14Mini iphone14mini;std::unique_ptr<iPhone> mini = director.create(iphone14mini);std::cout << "iPhone 14 Mini" << std::endl;mini->showInfo();std::cout << std::endl;iPhoneBuilder14PRO iphone14PRO;std::unique_ptr<iPhone> pro = director.create(iphone14PRO);std::cout << "iPhone 14 Mini" << std::endl;pro->showInfo();std::cout << std::endl;
}

在这里插入图片描述

sunny和merry号生产

现在我们开始着手把路飞的海贼船桑尼号 和梅利号使用生成器模式键造出来。
1、一共需要三个生成器类,一共父类,两个子类;
2、父类可以是一个抽象类,提供的建造函数都是虚函数;
3、在两个生成器子类中,使用建造函数分别将桑尼号 和梅利号各个零部件造出来。
如果我们仔细分析,发现还需要解决另外一个问题,通过生成器得到了海贼船的各个零部件,这些零部件必须有一个载体,那就是海贼船对象。因此,还需要提供一个或多个海贼船类。
因为桑尼号 和梅利号这两艘的差别非常之巨大,所以我们定义两个海贼船类,代码如下:

#include <iostream>
#include <memory>
#include <map>
#include <vector>
#include <string>
using namespace std;/*******************************_两个船类(Sunny号和Merry号)_*************************************/
//产品1:Sunny号
class Sunnyship
{
public://添加零件void addParts(string name){m_parts.push_back(name);}void showParts(){for (const auto& item : m_parts){cout << item << " ";cout << endl;}}
private:vector<string> m_parts;
};
//产品2:Merry号
class Merryship
{
public://添加零件void assemble(string name,string parts){m_parts.insert(make_pair(name,parts));}void showParts(){for (const auto& item : m_parts){cout << item.first << ": "<<item.second << " ";cout << endl;}}
private:map<string,string> m_parts;
};
/**************************************************************************************************/
/*****************************************_生成器类_*********************************************************/
//抽象生成器类
class ShipBuilder
{
public:virtual void reset() = 0;virtual void buildBody() = 0;virtual void buildWeapon() = 0;virtual void buildEngine() = 0;virtual void buildInterior() = 0;virtual ~ShipBuilder() {}
};
//具体生成器类:Sunny号生成器
class SunnyBuilder :public ShipBuilder
{
public:SunnyBuilder(){reset();}~SunnyBuilder(){if (m_sunny != nullptr){delete m_sunny;}}void reset() override{m_sunny = new Sunnyship;}void buildBody(){m_sunny->addParts("神树亚当的树干");}void buildWeapon(){m_sunny->addParts("狮吼炮");}void buildEngine(){m_sunny->addParts("可乐驱动");}void buildInterior(){m_sunny->addParts("豪华精装修的内饰");}Sunnyship* getSunny(){Sunnyship* ship = m_sunny;m_sunny = nullptr;return ship;}private:Sunnyship* m_sunny = nullptr;
};
//具体生成器类:Merry号生成器
class MerryBuilder :public ShipBuilder
{
public:MerryBuilder(){reset();}~MerryBuilder(){if (m_merry != nullptr){delete m_merry;}}void reset() override{m_merry = new class Merryship;}void buildBody(){m_merry->assemble("船体","优质木材");}void buildWeapon(){m_merry->assemble("武器","四门大炮");}void buildEngine(){m_merry->assemble("动力","蒸汽机");}void buildInterior(){m_merry->assemble("内饰","精装修");}Merryship* getMerry(){Merryship* ship = m_merry;m_merry = nullptr;return ship;}private:Merryship* m_merry = nullptr;
};
/******************************************_导演类_***********************************************/
class Director
{
public:void setBuilder(ShipBuilder* builder){m_builder = builder;}void builderSimpleShip(){m_builder->buildBody();m_builder->buildEngine();}void builderStandShip(){builderSimpleShip();m_builder->buildWeapon();}void builderRegalShip(){builderStandShip();m_builder->buildInterior();}
private:ShipBuilder* m_builder = nullptr;
};
/*******************************_代码测试_**************************************************/
//建造Sunny号
void buildSunny()
{Director director;SunnyBuilder Sbuild;//简约型director.setBuilder(&Sbuild);director.builderSimpleShip();Sunnyship* Sship = Sbuild.getSunny();Sship->showParts();delete Sship;}
int main()
{buildSunny();
}

在这里插入图片描述

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

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

相关文章

黑马mysql教程笔记(mysql8教程)基础篇——数据库相关概念、mysql安装及卸载、数据模型、SQL通用语法及分类(DDL、DML、DQL、DCL)

参考文章1&#xff1a;https://www.bilibili.com/video/BV1Kr4y1i7ru/ 参考文章2&#xff1a;https://dhc.pythonanywhere.com/article/public/1/ 文章目录 基础篇数据库相关概念&#xff08;数据库DataBase&#xff08;DB&#xff09;、数据库管理系统DataBase Management Sy…

数据分析视角中的商业分析学习笔记

数据分析一大堆&#xff0c;结果却是大家早就知道的结论&#xff1f;是工具和方法出问题了吗&#xff1f;真正原因可能是你的思维有误区。 为什么分析的这么辛苦&#xff0c;得出的结论大家早知道&#xff0c;谁谁都不满意&#xff1f;核心原因有3个&#xff1a; 分析之前&am…

UGUI交互组件Toggle

一.Toggle对象的构造 Toggle和Button类似&#xff0c;是交互组件的一种 如果所示&#xff0c;通过菜单创建了两个Toggle&#xff0c;Toggle2中更换了背景和标记资源 对象说明Toggle含有Toggle组件的对象Background开关背景Checkmark开关选中标记Label名称文本 二.Toggle组件属…

总结三:计算机网络面经

文章目录 1、简述静态路由和动态路由&#xff1f;2、说说有哪些路由协议&#xff0c;都是如何更新的&#xff1f;3、简述域名解析过程&#xff0c;本机如何干预域名解析&#xff1f;4、简述 DNS 查询服务器的基本流程是什么&#xff1f;DNS 劫持是什么&#xff1f;5、简述网关的…

Apollo Planning2.0决策规划算法代码详细解析 (2): vscode gdb单步调试环境搭建

前言: apollo planning2.0 在新版本中在降低学习和二次开发成本上进行了一些重要的优化,重要的优化有接口优化、task插件化、配置参数改造等。 GNU symbolic debugger,简称「GDB 调试器」,是 Linux 平台下最常用的一款程序调试器。GDB 编译器通常以 gdb 命令的形式在终端…

VUE3照本宣科——package.json与vite.config.js

VUE3照本宣科——package.json与vite.config.js VUE3照本宣科系列导航 前言一、package.json1.name2.version3.private4.scripts5.dependencies6.devDependencies 二、vite.config.js1.plugins2.resolve.alias3.base4.mode 三、VUE3照本宣科系列总结 VUE3照本宣科系列导航 1.VU…

ZRTP交叉编译与移植

1 ZRTP源码下载 这里采用的是libzrtp来自于freeswitch&#xff1a;libs/libzrtp。 2 ZRTP交叉编译 zrtp编译比较简单&#xff0c;采用configure进行编译在根目录心中zrtp编译脚本&#xff0c;只需要指定交叉编译工具链和安装地址即可。脚本如下所示&#xff1a; unset CC C…

三一充填泵:煤矿矸石无害化充填,煤炭绿色高效开采的破局利器

富煤贫油少气是我国的能源禀赋特征&#xff0c;决定了我国以煤炭为主的能源结构&#xff0c;煤炭为国民经济发展提供了重要的基础。煤炭开采过程会对土地、地下水、空气等环境造成较大的污染&#xff0c;但大宗固废煤矸石无害化充填的技术手段可以有效改善这样的情况&#xff0…

《视觉 SLAM 十四讲》V2 第 6 讲 非线性优化 【高斯牛顿法、列文伯格-马夸尔特方法 、Ceres 库 和 g2o库 】

文章目录 6.1.2 最小二乘 寻找下降增量 Δ x k \Delta\bm{x}_k Δxk​的 4 种方法6.2.1 一阶和二阶梯度法(最速下降法、牛顿法)6.2.2 高斯牛顿法6.2.3 列文伯格-马夸尔特方法 【阻尼牛顿法】【信赖区域法】 6.3 实践6.3.1 手写高斯牛顿法 【Code】6.3.2 谷歌的优化库 Ceres 【最…

计算机专业毕业设计项目推荐12-志愿者管理系统(Spring+Js+Mysql)

志愿者管理系统&#xff08;SpringJsMysql&#xff09; **介绍****各部分模块实现** 介绍 本系列(后期可能博主会统一为专栏)博文献给即将毕业的计算机专业同学们,因为博主自身本科和硕士也是科班出生,所以也比较了解计算机专业的毕业设计流程以及模式&#xff0c;在编写的过程…

【进阶C语言】排序函数(qsort)与模拟实现(回调函数的实例)

本章大致内容目录&#xff1a; 1.认识回调函数 2.排序函数qsort 3.模拟实现qsort 回调函数为C语言重要知识点&#xff0c;以函数指针为主要知识&#xff1b;下面介绍回调函数的定义、回调函数的库函数举例即库函数模拟实现。 一、回调函数 1.回调函数定义 回调函数就是一…

ZRTP协议与原理

1 ZRTP简介 ZRTP&#xff0c;全名Z Real-time Transport Protocol&#xff0c;是一种网络协议&#xff0c;旨在为实时通信提供安全性。与其它安全协议&#xff08;如TLS和IPsec&#xff09;不同&#xff0c;ZRTP专门为实时通信设计&#xff0c;包括音频和视频通话。它是由Phil…

基于FastAPI的文件上传和下载

基于FastAPI的文件上传和下载 一、前言 为了实现ASR的可视化界面&#xff0c;在各个博客中寻觅了一波找找文件上传和下载的例子&#xff0c;没有找到能完整实现这个功能的&#xff0c;有也只是有一部分&#xff08;菜菜求捞捞&#xff09;&#xff0c;看了甚是烦恼&#xff0…

数据结构刷题训练——二叉树篇(一)

&#x1f4d9;作者简介&#xff1a; 清水加冰&#xff0c;目前大二在读&#xff0c;正在学习C/C、Python、操作系统、数据库等。 &#x1f4d8;相关专栏&#xff1a;C语言初阶、C语言进阶、C语言刷题训练营、数据结构刷题训练营、有感兴趣的可以看一看。 欢迎点赞 &#x1f44d…

SaaS 电商设计 (二) 全链路解决方案概述和核心业务流程梳理

一.业务目标&技术目标 业务目标:完成多业态,多渠道的数字化运营 自有业务: O2O,B2C,B2B2C,S2B2b 平台业务:POPB2c,POPB2b,POPS2B2b 1.1 自有业务 O2O:全称Online to Offline.泛指的线上线下的业务融合.这种的情况分为两种情况,第一种通过线上的数字化运营引导线上用户线下…

AutoGen - 多个Agent开发LLM应用的框架

文章目录 关于安装使用关于 Enable Next-Gen Large Language Model Applications 用多个Agent开发LLM应用的框架,这些agent可相互交流以解决任务。 官网:https://microsoft.github.io/autogen/github : http://github.com/microsoft/autogendiscord : https://discord.com/i…

Flink的处理函数——processFunction

目录 一、处理函数概述 二、Process函数分类——8个 &#xff08;1&#xff09;ProcessFunction &#xff08;2&#xff09;KeyedProcessFunction &#xff08;3&#xff09;ProcessWindowFunction &#xff08;4&#xff09;ProcessAllWindowFunction &#xff…

vue +element 批量删除

1.拿到当前勾选状态 在el-table里边去写 单选用第一个 多选用第二个 select"selectHandle" :当用户手动勾选数据行的 Checkbox 时触发的事件 select-all"selectHandle":当用户手动勾选全选 Checkbox 时触发的事件// 点击勾选选择器selectHandle(selection…

华为云云耀云服务器L实例评测|云耀云服务器L实例部署DjangoBlog个人博客系统

华为云云耀云服务器L实例评测&#xff5c;云耀云服务器L实例部署DjangoBlog个人博客系统 一、云耀云服务器L实例介绍1.1 云耀云服务器L实例简介1.2 云耀云服务器L实例特点 二、DjangoBlog介绍2.1 DjangoBlog介绍2.2 DjangoBlog特点 三、本次实践介绍3.1 本次实践简介3.2 本次环…

【2023双非保研】信管跨保计算机大类的记录(东南、川大、重大、东北、西电、南理工、杭高院、河海、东华、天大等)

以此篇博客记录我的保研之旅 目录 一、个人情况 二、夏令营 1、国科大杭高院&#xff08;线下&#xff09; 2、南信工&#xff08;线下&#xff09; 3、华中师范&#xff08;线上or线下&#xff09; 4、浙大软件&#xff08;线上&#xff09; 5、东华大学&#xff08;线…