【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.rhkb.cn/news/149521.html

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

相关文章

[论文工具] LaTeX论文撰写常见用法及实战技巧归纳(持续更新)

祝大家中秋国庆双节快乐&#xff01; 回过头来&#xff0c;我们在编程过程中&#xff0c;经常会遇到各种各样的问题。然而&#xff0c;很多问题都无法解决&#xff0c;网上夹杂着各种冗余的回答&#xff0c;也缺乏系统的实战技巧归纳。为更好地从事科学研究和编程学习&#xff…

自动驾驶:未来的道路上的挑战与机遇

自动驾驶&#xff1a;未来的道路上的挑战与机遇 文章目录 引言安全与道路事故的减少交通拥堵的缓解城市规划的变革技术和法律挑战结语 2023星火培训【专项营】Apollo开发者社区布道师倾力打造&#xff0c;包含PnC、新感知等的全新专项课程上线了。理论与实践相结合&#xff0c;…

Mac上protobuf环境构建-java

参考文献 getting-started 官网pb java介绍 maven protobuf插件 简单入门1 简单入门2 1. protoc编译器下载安装 https://github.com/protocolbuffers/protobuf/releases?page10 放入.zshrc中配置环境变量  ~/IdeaProjects/test2/ protoc --version libprotoc 3.12.1  …

Spring基础以及核心概念(IoC和DIQ)

1.Spring是什么 Spring是包含了众多工具方法的IoC容器 2.loC&#xff08;Inversion of Control &#xff09;是什么 IoC:控制反转,Spring是一个控制反转容器(控制反转对象的生命周期) Spring是一个loC容器&#xff0c;我们之前学过的List/Map就是数据存储的容器&#xff0c;to…

数据结构—栈、队列、链表

一、栈 Stack&#xff08;存取O(1)&#xff09; 先进后出&#xff0c;进去123&#xff0c;出来321。 基于数组&#xff1a;最后一位为栈尾&#xff0c;用于取操作。 基于链表&#xff1a;第一位为栈尾&#xff0c;用于取操作。 1.1、数组栈 /*** 基于数组实现的顺序栈&#…

【C++】运算符重载 ⑧ ( 左移运算符重载 | 友元函数 / 成员函数 实现运算符重载 | 类对象 使用 左移运算符 )

文章目录 一、左移运算符重载1、友元函数 / 成员函数 实现运算符重载2、类对象 使用 左移运算符3、左移运算符 << 重载 二、完整代码示例 一、左移运算符重载 1、友元函数 / 成员函数 实现运算符重载 运算符重载 的正规写法一般都是 使用 成员函数 的形式 实现的 ; 加法…

Android笔记:Android 组件化方案探索与思考

组件化项目&#xff0c;通过gradle脚本&#xff0c;实现module在编译期隔离&#xff0c;运行期按需加载&#xff0c;实现组件间解耦&#xff0c;高效单独调试。 先来一张效果图 组件化初衷 APP版本不断的迭代&#xff0c;新功能的不断增加&#xff0c;业务也会变的越来越复杂…

速学数据结构 | 手把手教你会单链表的构建方式

&#x1f3ac; 鸽芷咕&#xff1a;个人主页 &#x1f525; 个人专栏: 《初阶数据结构》《C语言进阶篇》 ⛺️生活的理想&#xff0c;就是为了理想的生活! 文章目录 &#x1f4cb; 前言1. 什么是链表1.1 链表的物理结构1.2 链表的种类 2. 链表的实现一. SList.h 单链表的声明3.…

React antd Table点击下一页后selectedRows丢失之前页选择内容的问题

一、问题 使用了React antd 的<Table>标签&#xff0c;是这样记录选中的行id与行内容的&#xff1a; <TabledataSource{data.list}rowSelection{{selectedRowKeys: selectedIdsInSearchTab,onChange: this.onSelectChange,}} // 表格是否可复选&#xff0c;加 type: …

智慧公厕:将科技融入日常生活的创新之举

智慧公厕是当今社会中一项备受关注的创新项目。通过将科技融入公厕设计和管理中&#xff0c;这些公厕不仅能够提供更便利、更卫生的使用体验&#xff0c;还能够极大地提升城市形象和居民生活质量。本文将以智慧公厕领先厂家广州中期科技有限公司&#xff0c;大量的精品案例项目…

vue3中使用return语句返回this.$emit(),在同一行不执行,换行后才执行,好奇怪!

今天练习TodoList任务列表案例,该案例效果如图所示&#xff1a; 此案例除了根组件App.vue&#xff0c;还有TodoList、TodoInput、TodoButton三个子组件。 因为有视频讲解&#xff0c;在制作TodoList、TodoInput时很顺利&#xff0c;只是在完成TodoButton这个组件时出了点问题…

网络爬虫——urllib(1)

前言&#x1f36d; ❤️❤️❤️网络爬虫专栏更新中&#xff0c;各位大佬觉得写得不错&#xff0c;支持一下&#xff0c;感谢了&#xff01;❤️❤️❤️ 前篇简单介绍了什么是网络爬虫及相关概念&#xff0c;这篇开始讲解爬虫中的第一个库——urllib。 urllib&#x1f36d; …

UG\NX二次开发 用程序修改“用户默认设置”

文章作者:里海 来源网站:《里海NX二次开发3000例专栏》 感谢粉丝订阅 感谢 wuguoyana、duanxheng 两位粉丝订阅本专栏,非常感谢。 简介 可以用程序修改“用户默认设置”吗?下面是用代码修改“用户默认设置->基本环境->用户界面->操作记录->操作记录语言”的例子…

【Python+requests+unittest+excel】实现接口自动化测试框架

一、框架结构&#xff1a; 工程目录 二、Case文件设计 三、基础包 base3.1 封装get/post请求&#xff08;runmethon.py&#xff09; 1 import requests2 import json3 class RunMethod:4 def post_main(self,url,data,headerNone):5 res None6 if header …

【AI视野·今日Robot 机器人论文速览 第四十六期】Tue, 3 Oct 2023

AI视野今日CS.Robotics 机器人学论文速览 Tue, 3 Oct 2023 Totally 76 papers &#x1f449;上期速览✈更多精彩请移步主页 Interesting: &#x1f4da;Aerial Interaction with Tactile, 无人机与触觉的结合&#xff0c;实现空中交互与相互作用。(from CMU) website&#…

10.3倒水问题(几何图论建模)

坐标图中每一个位置都对应一个合法的状态&#xff0c;BC对5升杯子做出限制&#xff0c;AD对9升杯子作出限制 每次倒水&#xff0c;都只能把目标杯子装满&#xff0c;否则无法确定倒出水的多少与目标杯子此时水的容量 所以例如&#xff0c;倒5升杯子时&#xff0c;只能要么把5…

Python逐日填补Excel中的日期并用0值填充缺失日期的数据

本文介绍基于Python语言&#xff0c;读取一个不同的列表示不同的日期的.csv格式文件&#xff0c;将其中缺失的日期数值加以填补&#xff1b;并用0值对这些缺失日期对应的数据加以填充的方法。 首先&#xff0c;我们明确一下本文的需求。现在有一个.csv格式文件&#xff0c;其第…

Pyhon-每日一练(1)

&#x1f308;write in front&#x1f308; &#x1f9f8;大家好&#xff0c;我是Aileen&#x1f9f8;.希望你看完之后&#xff0c;能对你有所帮助&#xff0c;不足请指正&#xff01;共同学习交流. &#x1f194;本文由Aileen_0v0&#x1f9f8; 原创 CSDN首发&#x1f412; 如…

竞赛选题 深度学习 opencv python 实现中国交通标志识别_1

文章目录 0 前言1 yolov5实现中国交通标志检测2.算法原理2.1 算法简介2.2网络架构2.3 关键代码 3 数据集处理3.1 VOC格式介绍3.2 将中国交通标志检测数据集CCTSDB数据转换成VOC数据格式3.3 手动标注数据集 4 模型训练5 实现效果5.1 视频效果 6 最后 0 前言 &#x1f525; 优质…

拆解常见的6类爆款标题写作技巧!

究竟是先写好文章再拟标题还是先确定标题再写文章呢&#xff1f;很多写稿小白都会有这样的疑惑。 在“人人皆可新媒体”的时代&#xff0c;公众号推文类型琳琅满目&#xff0c;每个人都可以建立自己的公众号&#xff0c;写出自己想写的文章。 但怎样起标题、起什么样的标题&a…