C++创建型模式之生成器模式
解决的问题
生成器模式(Builder Pattern)主要解决复杂对象的构建问题。当一个对象的创建过程非常复杂,涉及多个步骤和多个部件时,使用生成器模式可以将对象的构建过程与其表示分离,使得同样的构建过程可以创建不同的表示。
适用场景
- 复杂对象的构建:当对象的构建过程非常复杂,涉及多个步骤和多个部件时。
- 不同的构建过程:当需要不同的表示时,可以使用相同的构建过程。
- 逐步构建:当对象的构建过程可以逐步进行时。
模式的参与者角色
- Builder(生成器接口):定义构建产品的各个部件的抽象接口。
- ConcreteBuilder(具体生成器):实现
Builder接口,负责构建产品的各个部件。 - Product(产品):表示正在构建的复杂对象。
- Director(指导者):使用
Builder接口来构建产品。
以生产汽车为例的生成器模式示例代码
#include <iostream>
#include <string>// 产品类:汽车
class Car {
public:void setBody(const std::string& body) { body_ = body; }void setEngine(const std::string& engine) { engine_ = engine; }void setWheels(const std::string& wheels) { wheels_ = wheels; }void setInterior(const std::string& interior) { interior_ = interior; }void show() const {std::cout << "Car Configuration: " << std::endl;std::cout << "Body: " << body_ << std::endl;std::cout << "Engine: " << engine_ << std::endl;std::cout << "Wheels: " << wheels_ << std::endl;std::cout << "Interior: " << interior_ << std::endl;}private:std::string body_;std::string engine_;std::string wheels_;std::string interior_;
};// 抽象生成器接口
class CarBuilder {
public:virtual ~CarBuilder() {}virtual void buildBody() = 0;virtual void buildEngine() = 0;virtual void buildWheels() = 0;virtual void buildInterior() = 0;virtual Car* getCar() = 0;
};// 具体生成器:SUV 汽车
class SUVBuilder : public CarBuilder {
public:SUVBuilder() { car_ = new Car(); }~SUVBuilder() { delete car_; }void buildBody() override { car_->setBody("SUV Body"); }void buildEngine() override { car_->setEngine("SUV Engine"); }void buildWheels() override { car_->setWheels("SUV Wheels"); }void buildInterior() override { car_->setInterior("SUV Interior"); }Car* getCar() override { return car_; }private:Car* car_;
};// 具体生成器:Sedan 汽车
class SedanBuilder : public CarBuilder {
public:SedanBuilder() { car_ = new Car(); }~SedanBuilder() { delete car_; }void buildBody() override { car_->setBody("Sedan Body"); }void buildEngine() override { car_->setEngine("Sedan Engine"); }void buildWheels() override { car_->setWheels("Sedan Wheels"); }void buildInterior() override { car_->setInterior("Sedan Interior"); }Car* getCar() override { return car_; }private:Car* car_;
};// 指导者
class Director {
public:void setBuilder(CarBuilder* builder) { builder_ = builder; }Car* constructCar() {builder_->buildBody();builder_->buildEngine();builder_->buildWheels();builder_->buildInterior();return builder_->getCar();}private:CarBuilder* builder_;
};// 客户端代码
int main() {Director director;// 创建 SUVstd::cout << "Building SUV..." << std::endl;SUVBuilder suvBuilder;director.setBuilder(&suvBuilder);Car* suv = director.constructCar();suv->show();delete suv;// 创建 Sedanstd::cout << "\nBuilding Sedan..." << std::endl;SedanBuilder sedanBuilder;director.setBuilder(&sedanBuilder);Car* sedan = director.constructCar();sedan->show();delete sedan;return 0;
}
代码说明
- Car 类表示正在构建的汽车产品,包含汽车的各个部件。
- CarBuilder 是一个抽象生成器接口,定义了构建汽车各个部件的方法和一个获取最终产品的接口。
- SUVBuilder 和 SedanBuilder 是具体生成器类,分别实现了
CarBuilder接口,用于构建 SUV 和 Sedan 汽车。 - Director 类负责使用
CarBuilder接口来构建汽车。它通过调用生成器的各个构建方法来逐步构建汽车。 - Client 在
main函数中使用Director和具体生成器来构建不同类型的汽车,并展示汽车配置。
总结
生成器模式通过将复杂对象的构建过程与其表示分离,使得同样的构建过程可以创建不同的表示。在需要逐步构建复杂对象或需要不同表示的场景中,生成器模式非常有用。
模板方法(Template Method)模式与生成器(Builder)模式
形式相似点
- 抽象类与具体类:两种模式都涉及抽象类(或接口)和具体实现类。
- 分步构建:都需要分步骤构建复杂对象或执行算法。
目的的不同点
- 模板方法模式:定义一个算法的框架,允许子类在不改变算法结构的情况下重新定义算法的某些步骤。目的是为了代码复用和算法的一致性。
- 生成器模式:将复杂对象的构建过程与其表示分离,使得同样的构建过程可以创建不同的表示。目的是为了构建复杂对象时的灵活性和可扩展性。
模板方法模式的代码示例
#include <iostream>
#include <string>// 抽象类,定义模板方法
class AbstractClass {
public:// 模板方法void templateMethod() {step1();step2();step3();}protected:virtual void step1() = 0;virtual void step2() = 0;virtual void step3() = 0;
};// 具体类1
class ConcreteClass1 : public AbstractClass {
protected:void step1() override {std::cout << "ConcreteClass1: Step 1" << std::endl;}void step2() override {std::cout << "ConcreteClass1: Step 2" << std::endl;}void step3() override {std::cout << "ConcreteClass1: Step 3" << std::endl;}
};// 具体类2
class ConcreteClass2 : public AbstractClass {
protected:void step1() override {std::cout << "ConcreteClass2: Step 1" << std::endl;}void step2() override {std::cout << "ConcreteClass2: Step 2" << std::endl;}void step3() override {std::cout << "ConcreteClass2: Step 3" << std::endl;}
};// 客户端代码
int main() {AbstractClass* class1 = new ConcreteClass1();class1->templateMethod();delete class1;std::cout << std::endl;AbstractClass* class2 = new ConcreteClass2();class2->templateMethod();delete class2;return 0;
}
生成器模式的代码示例
#include <iostream>
#include <string>// 产品类
class Product {
public:void setPartA(const std::string& partA) { partA_ = partA; }void setPartB(const std::string& partB) { partB_ = partB; }void setPartC(const std::string& partC) { partC_ = partC; }void show() const {std::cout << "Product parts: " << partA_ << ", " << partB_ << ", " << partC_ << std::endl;}private:std::string partA_;std::string partB_;std::string partC_;
};// 抽象生成器接口
class Builder {
public:virtual ~Builder() {}virtual void buildPartA() = 0;virtual void buildPartB() = 0;virtual void buildPartC() = 0;virtual Product* getProduct() = 0;
};// 具体生成器
class ConcreteBuilder : public Builder {
public:ConcreteBuilder() { product_ = new Product(); }~ConcreteBuilder() { delete product_; }void buildPartA() override { product_->setPartA("PartA"); }void buildPartB() override { product_->setPartB("PartB"); }void buildPartC() override { product_->setPartC("PartC"); }Product* getProduct() override { return product_; }private:Product* product_;
};// 指导者
class Director {
public:void setBuilder(Builder* builder) { builder_ = builder; }Product* constructProduct() {builder_->buildPartA();builder_->buildPartB();builder_->buildPartC();return builder_->getProduct();}private:Builder* builder_;
};// 客户端代码
int main() {Director director;// 创建具体生成器ConcreteBuilder builder;director.setBuilder(&builder);// 构建产品Product* product = director.constructProduct();product->show();delete product;return 0;
}
代码说明
模板方法示例
- AbstractClass:定义了一个模板方法
templateMethod(),其中包含了三个抽象步骤step1(),step2(),step3()。 - ConcreteClass1 和 ConcreteClass2:具体子类,分别实现了抽象步骤,但模板方法的结构保持不变。
- 客户端代码:通过创建
ConcreteClass1和ConcreteClass2的对象,调用templateMethod()方法来执行算法,子类可以在不改变算法结构的情况下重新定义算法的某些步骤。
生成器模式示例
- Product:表示正在构建的复杂对象。
- Builder:抽象生成器接口,定义了构建产品的各个部件的方法和一个获取最终产品的接口。
- ConcreteBuilder:具体生成器类,实现了
Builder接口,负责构建产品的各个部件。 - Director:指导者类,使用
Builder接口来构建产品。通过调用生成器的各个构建方法来逐步构建产品。 - 客户端代码:通过
Director和ConcreteBuilder来构建产品,并展示产品配置。
总结
- 模板方法模式:目的是为了代码复用和算法的一致性,通过定义算法的框架,允许子类在不改变算法结构的情况下重新定义算法的某些步骤。
- 生成器模式:目的是为了构建复杂对象时的灵活性和可扩展性,通过将复杂对象的构建过程与其表示分离,使得同样的构建过程可以创建不同的表示。
相关文章:
C++创建型模式之生成器模式
解决的问题 生成器模式(Builder Pattern)主要解决复杂对象的构建问题。当一个对象的创建过程非常复杂,涉及多个步骤和多个部件时,使用生成器模式可以将对象的构建过程与其表示分离,使得同样的构建过程可以创建不同的表…...
鸿蒙NEXT应用示例:切换图片动画
【引言】 在鸿蒙NEXT应用开发中,实现图片切换动画是一项常见的需求。本文将介绍如何使用鸿蒙应用框架中的组件和动画功能,实现不同类型的图片切换动画效果。 【环境准备】 电脑系统:windows 10 开发工具:DevEco Studio NEXT B…...
postgresql(功能最强大的开源数据库)继承特性和分区实现
PostgreSQL实现了表继承,在多重表继承下,对上亿条不同类别的数据条目进行按型号、按月份双层分区管理,既可在总表查阅所有条目的共有字段,也可在各类型字表查询附加字段,非常高效。 分区是通过继承的方式来实现的&…...
论文笔记(五十六)VIPose: Real-time Visual-Inertial 6D Object Pose Tracking
VIPose: Real-time Visual-Inertial 6D Object Pose Tracking 文章概括摘要I. INTRODACTIONII. 相关工作III. APPROACHA. 姿态跟踪工作流程B. VIPose网络 文章概括 引用: inproceedings{ge2021vipose,title{Vipose: Real-time visual-inertial 6d object pose tra…...
微服务治理详解
文章目录 什么是微服务架构为什么要使用微服务单体架构如何转向微服务架构服务治理服务治理治的是什么服务注册与发现服务熔断降级服务网关服务调用服务负载均衡服务配置中心 微服务解决方案SpringCloud体系EurekaHystrixGatewayOpenFeignRibbonConfig SpringCloud Alibaba体系…...
“南海明珠”-黄岩岛(民主礁)领海基线WebGIS绘制实战
目录 前言 一、关于岛屿的基点位置 1、领海基点 二、基点坐标的转换 1、最底层的左边转换 2、单个经纬度坐标点转换 3、完整的转换 三、基于天地图进行WebGIS展示 1、领海基点的可视化 2、重要城市距离计算 四、总结 前言 南海明珠黄岩岛,这座位于南海的…...
Oracle数据库 创建dblink的过程及其用法详解
前言 dblink是Oracle数据库中用于连接不同数据库实例的一种机制。通过dblink,用户可以在一个数据库实例中直接查询或操作另一个数据库实例中的表、视图或存储过程。 dblink的作用主要体现在以下几个方面: 跨数据库操作:允许用户…...
Linux从0——1之shell编程4
声明! 学习视频来自B站up主 **泷羽sec** 有兴趣的师傅可以关注一下,如涉及侵权马上删除文章,笔记只是方便各位师傅的学习和探讨,文章所提到的网站以及内容,只做学习交流,其他均与本人以及泷羽sec团队无关&a…...
pycharm快速更换虚拟环境
目录 1. 选择Conda 虚拟环境2. 创建环境3. 直接选择现有虚拟环境 1. 选择Conda 虚拟环境 2. 创建环境 3. 直接选择现有虚拟环境...
MVVM框架
MVVM由以下三个内容构成: Model:数据模型View:界面ViewModel:作为桥梁负责沟通View和Model 在JQuery时期,如果需要刷新UI,需要先取到对应的 DOM 再更新 UI,这样数据和业务的逻辑就和⻚⾯有强耦合。 在 MVVM 中,UI 是…...
数据仓库在大数据处理中的作用
数据仓库(Data Warehouse,简称DW或DWH)是一个面向主题的、集成的、相对稳定的、反映历史变化的数据集合,用于支持管理决策。以下是对数据仓库及其在大数据处理中作用的详细解释: 一、数据仓库的定义 面向主题&#x…...
前端Javascript、Vue、CSS等场景面试题目(二)
前端面试场景题目(一)-CSDN博客 针对您提供的前端场景面试题目,以下是详细的回答: 1. 如何通过 CSS 实现美观的自定义复选框和单选按钮? 方法:使用 CSS 伪元素 ::before 和 ::after,以及隐藏…...
鸿蒙学习生态应用开发能力全景图-开发者支持平台(5)
鸿蒙相关平台作用: 开发者社区:开发者技术交流平台,帮助开发者探索开发实践、交流心得经验、获悉业界动态、答疑解惑。 开发者学堂:聚合官方鸿蒙生态课程,课程有慕课、微课、直播课、训练营等多种形式ÿ…...
计算机网络各层设备总结归纳(更新ing)
计算机网络按照OSI(开放式系统互联)模型分为七层,每一层都有其特定的功能和对应的网络设备。以下是各层对应的设备: 1. 物理层(Physical Layer) 设备:中继器(Repeater)、集线器…...
3. Spring Cloud Eureka 服务注册与发现(超详细说明及使用)
3. Spring Cloud Eureka 服务注册与发现(超详细说明及使用) 文章目录 3. Spring Cloud Eureka 服务注册与发现(超详细说明及使用)前言1. Spring Cloud Eureka 的概述1.1 服务治理概述1.2 服务注册与发现 2. 实践:创建单机 Eureka Server 注册中心2.1 需求说明 图解…...
品牌如何利用大数据工具,进行消费者洞察分析?
存量竞争的时代, 消费者聆听是品牌持续增长的关键,借助大数据的消费者数据洞察,可以帮助品牌分析消费者的所思所想及行为特征,获取消费者对产品的需求痛点、使用感受,对品牌的评价口碑等,从而帮助品牌更好地…...
鸿蒙实现 web 传值
前言:安卓和 IOS 加载 H5 的时候,都有传值给到 H5 或者接收 H5 值,鸿蒙也可传值和接收 H5 的内容,以下是鸿蒙传值给 H5 端的具体操作 一: 定义好 H5 和鸿蒙传值的方法名,两端必须保持方法名一致 // xxx.ets import …...
uniapp vuex的使用
实现组件全局(数据)管理的一种机制,可以方便的实现组件之间共享数据,不同于上述三种传递值的方式。 可以把vuex当成一个store仓库,可以集中管理共享的数据,并且存储在vuex中的数据都是响应式的,…...
RabbitMQ实战启程:从原理到部署的全方位探索(上)
文章目录 一、RabbitMQ简介1.1、概述1.2、特性 二、RabbitMQ原理架构三、RabbitMQ应用场景3.1 简单模式3.2 工作模式3.3 发布订阅3.4 路由模式3.5 主题订阅模式 四、同类中间件对比五、RabbitMQ部署5.1 单机部署5.1.1 安装erlang5.1.2 安装rabbitmq 5.2 集群部署(镜…...
【论文复现】轻松利用自适应特征融合实现去雾
📝个人主页🌹:Eternity._ 🌹🌹期待您的关注 🌹🌹 ❀ 智慧医疗 介绍创新点网络结构特征提取阶段自适应融合阶段图像重建阶段上下文增强模块CEM特征融合模块AFM 结果分析 提示 论文题目࿱…...
LBE-LEX系列工业语音播放器|预警播报器|喇叭蜂鸣器的上位机配置操作说明
LBE-LEX系列工业语音播放器|预警播报器|喇叭蜂鸣器专为工业环境精心打造,完美适配AGV和无人叉车。同时,集成以太网与语音合成技术,为各类高级系统(如MES、调度系统、库位管理、立库等)提供高效便捷的语音交互体验。 L…...
【力扣数据库知识手册笔记】索引
索引 索引的优缺点 优点1. 通过创建唯一性索引,可以保证数据库表中每一行数据的唯一性。2. 可以加快数据的检索速度(创建索引的主要原因)。3. 可以加速表和表之间的连接,实现数据的参考完整性。4. 可以在查询过程中,…...
安宝特方案丨XRSOP人员作业标准化管理平台:AR智慧点检验收套件
在选煤厂、化工厂、钢铁厂等过程生产型企业,其生产设备的运行效率和非计划停机对工业制造效益有较大影响。 随着企业自动化和智能化建设的推进,需提前预防假检、错检、漏检,推动智慧生产运维系统数据的流动和现场赋能应用。同时,…...
dedecms 织梦自定义表单留言增加ajax验证码功能
增加ajax功能模块,用户不点击提交按钮,只要输入框失去焦点,就会提前提示验证码是否正确。 一,模板上增加验证码 <input name"vdcode"id"vdcode" placeholder"请输入验证码" type"text&quo…...
macOS多出来了:Google云端硬盘、YouTube、表格、幻灯片、Gmail、Google文档等应用
文章目录 问题现象问题原因解决办法 问题现象 macOS启动台(Launchpad)多出来了:Google云端硬盘、YouTube、表格、幻灯片、Gmail、Google文档等应用。 问题原因 很明显,都是Google家的办公全家桶。这些应用并不是通过独立安装的…...
如何将联系人从 iPhone 转移到 Android
从 iPhone 换到 Android 手机时,你可能需要保留重要的数据,例如通讯录。好在,将通讯录从 iPhone 转移到 Android 手机非常简单,你可以从本文中学习 6 种可靠的方法,确保随时保持连接,不错过任何信息。 第 1…...
Java-41 深入浅出 Spring - 声明式事务的支持 事务配置 XML模式 XML+注解模式
点一下关注吧!!!非常感谢!!持续更新!!! 🚀 AI篇持续更新中!(长期更新) 目前2025年06月05日更新到: AI炼丹日志-28 - Aud…...
Robots.txt 文件
什么是robots.txt? robots.txt 是一个位于网站根目录下的文本文件(如:https://example.com/robots.txt),它用于指导网络爬虫(如搜索引擎的蜘蛛程序)如何抓取该网站的内容。这个文件遵循 Robots…...
NFT模式:数字资产确权与链游经济系统构建
NFT模式:数字资产确权与链游经济系统构建 ——从技术架构到可持续生态的范式革命 一、确权技术革新:构建可信数字资产基石 1. 区块链底层架构的进化 跨链互操作协议:基于LayerZero协议实现以太坊、Solana等公链资产互通,通过零知…...
Spring AI与Spring Modulith核心技术解析
Spring AI核心架构解析 Spring AI(https://spring.io/projects/spring-ai)作为Spring生态中的AI集成框架,其核心设计理念是通过模块化架构降低AI应用的开发复杂度。与Python生态中的LangChain/LlamaIndex等工具类似,但特别为多语…...
