深圳外贸网站建设服务哪家好/福州百度推广排名
目录
1.简介
2.结构
3.使用场景
4.实例
5.优缺点
6.与其他模式的关系
7.总结
1.简介
生成器模式(Builder Pattern)是一种创建型设计模式,它允许你通过一步一步构建复杂对象,而不是通过一个包含大量参数的构造函数或方法。该模式特别适用于需要生成的对象具有多个可选属性,且这些属性的组合会导致大量构造函数重载的情况。
生成器模式通过将对象的构建过程分解成多个步骤,使得每一步都可以单独配置。这样不仅提高了代码的可读性和可维护性,还使得构建过程更加灵活和可扩展。
与其他创建型模式不同的是,生成器模式允许你在一个过程中创建一个对象,而无需等待所有部分都准备好。这种模式特别适用于需要构造不同表示或状态的复杂对象时。
2.结构
生成器模式的UML结构图如下所示:
1) 生成器(Builder)接口声明在所有类型生成器中通用的产品构造步骤。
2) 具体生成器(Concrete Builders)提供构造过程的不同实现。具体生成器也可以构造不遵循通用接口的产品。
3) 产品(Products)是最终生成的对象。由不同生成器构造的产品无需属于同一类层次结构或接口。
4) 主管(Director)类定义调用构造步骤的顺序,这样你就可以创建和复用特定的产品配置。
5) 客户端(Client)必须将某个生成器对象与主管类关联。一般情况下,你只需通过主管类构造函数的参数进行一次性关联即可。此后主管类就能使用生成器对象完成后续所有的构造任务。但在客户端将生成器对象传递给主管类制造方法时还有另一种方式。在这种情况下,你在使用主管类生产产品时每次都可以使用不同的生成器。
3.使用场景
1)使用生成器模式可避免“重叠构造函数(telescopicconstructor)”的出现。
假设你的构造函数中有十个可选参数,那么调用该函数会非常不方便;因此,你需要重载这个构造函数,新建几个只有较少参数的简化版。但这些构造函数仍需调用主构造函数,传递一些默认数值来替代省略掉的参数。生成器模式让你可以分步骤生成对象,而且允许你仅使用必须的步骤。应用该模式后,你再也不需要将几十个参数塞进构造函数里了。
2)当你希望使用代码创建不同形式的产品(例如石头或木头房屋)时,可使用生成器模式。
如果你需要创建的各种形式的产品,它们的制造过程相似且仅有细节上的差异,此时可使用生成器模式。基本生成器接口中定义了所有可能的制造步骤,具体生成器将实现这些步骤来制造特定形式的产品。同时,主管类将负责管理制造步骤的顺序。
3)使用生成器构造组合树或其他复杂对象。
当一个对象的构建过程非常复杂,涉及多个步骤和多个部件时,使用生成器模式可以将对象的构建过程与其表示分离,使得同样的构建过程可以创建不同的表示。
例如,构建一个汽车对象可能涉及设置车身、引擎、车轮和内饰等多个部件,每个部件都有多种选择。使用生成器模式,可以逐步构建汽车对象,并根据需要选择不同的部件。
4.实例
下面我将展示一个稍微复杂一些的应用场景,即构建一个包含多个可选组件的计算机配置对象。
首先,我们定义一个Computer
类,它代表我们要构建的计算机对象:
#include <iostream>
#include <string>
#include <vector>
#include <memory>class Computer {
private:std::string caseType;std::string cpu;std::string gpu;std::string ram;std::string storage;std::vector<std::string> peripherals;// 禁止直接实例化Computer(const std::string& caseType, const std::string& cpu, const std::string& gpu,const std::string& ram, const std::string& storage,const std::vector<std::string>& peripherals): caseType(caseType), cpu(cpu), gpu(gpu), ram(ram), storage(storage), peripherals(peripherals) {}friend class ComputerBuilder;public:void display() const {std::cout << "Case Type: " << caseType << "\n";std::cout << "CPU: " << cpu << "\n";std::cout << "GPU: " << gpu << "\n";std::cout << "RAM: " << ram << "\n";std::cout << "Storage: " << storage << "\n";std::cout << "Peripherals: ";for (const auto& peripheral : peripherals) {std::cout << peripheral << " ";}std::cout << "\n";}
};
接下来,我们定义一个ComputerBuilder
类,用于逐步构建Computer
对象:
class ComputerBuilder {
protected:std::string caseType;std::string cpu;std::string gpu;std::string ram;std::string storage;std::vector<std::string> peripherals;public:virtual ~ComputerBuilder() = default;ComputerBuilder& setCaseType(const std::string& caseType) {this->caseType = caseType;return *this;}ComputerBuilder& setCpu(const std::string& cpu) {this->cpu = cpu;return *this;}ComputerBuilder& setGpu(const std::string& gpu) {this->gpu = gpu;return *this;}ComputerBuilder& setRam(const std::string& ram) {this->ram = ram;return *this;}ComputerBuilder& setStorage(const std::string& storage) {this->storage = storage;return *this;}ComputerBuilder& addPeripheral(const std::string& peripheral) {peripherals.push_back(peripheral);return *this;}virtual Computer build() const = 0;
};
注意,这里我们将ComputerBuilder
定义为一个抽象类,并声明了一个纯虚函数build
,这样我们就可以有不同的具体实现来构建不同类型的计算机。
现在,我们定义一个具体的GamingComputerBuilder
类来构建游戏计算机:
class GamingComputerBuilder : public ComputerBuilder {
public:GamingComputerBuilder() {// 可以设置一些默认配置setCaseType("ATX Mid Tower");setCpu("Intel i9");// ... 其他默认配置}Computer build() const override {return Computer(caseType, cpu, gpu, ram, storage, peripherals);}
};
在GamingComputerBuilder
中,我们可以设置一些默认配置,或者覆盖父类的方法来提供特定的配置选项。
最后,我们定义一个ComputerDirector
类(可选)来管理构建过程,并展示如何使用这些类来构建一个计算机对象:
class ComputerDirector {
private:ComputerBuilder* builder;public:ComputerDirector(ComputerBuilder* builder) : builder(builder) {}void setBuilder(ComputerBuilder* builder) {this->builder = builder;}Computer constructGamingComputer() {builder->setGpu("NVIDIA RTX 3090");builder->setRam("32GB DDR4");builder->setStorage("2TB SSD");builder->addPeripheral("Gaming Keyboard");builder->addPeripheral("Gaming Mouse");// ... 其他配置return builder->build();}
};int main() {GamingComputerBuilder gamingBuilder;ComputerDirector director(&gamingBuilder);// 或者使用自定义的构建步骤// gamingBuilder.setCaseType("Custom Case");// ... 其他设置// Computer customComputer = gamingBuilder.build();Computer gamingComputer = director.constructGamingComputer();gamingComputer.display();return 0;
}
在这个例子中,我们展示了如何使用生成器模式来构建一个包含多个可选组件的计算机配置对象。通过定义抽象的ComputerBuilder
类和具体的GamingComputerBuilder
类,我们可以灵活地构建不同类型的计算机,并且可以通过ComputerDirector
类来管理构建过程(尽管在这个例子中ComputerDirector
是可选的,但在更复杂的场景中它可能会很有用)。
5.优缺点
优点:
● 你可以分步创建对象,暂缓创建步骤或递归运行创建步骤。
● 生成不同形式的产品时,你可以复用相同的制造代码。
● 单一职责原则。你可以将复杂构造代码从产品的业务逻辑中分离出来。
由于该模式需要新增多个类,因此代码整体复杂程度会有所增加。
6.与其他模式的关系
与工厂模式的关系
- 工厂模式:主要用于生产各种对象,这些对象通常是兄弟类,继承自同一个基类。兄弟子类通过实现基类接口,展现不同的行为,并由工厂函数创建。然而,工厂模式在创建对象时并不关注构造细节,因此在处理复杂对象的生成时可能会显得力不从心。
- 生成器模式:同样用于对象的生成,但更侧重于构造细节,增加了额外的构建流程,以便处理复杂对象的构建需求。生成器模式将对象构造的代码从产品类中抽取出来,放在一个名为生成器的独立对象中,并允许通过不同的生成器来创建不同形式的对象。
- 对比:相较于工厂模式,生成器模式提供了更灵活和详细的对象构造方式。当对象相对简单时,可以使用工厂模式;而当对象复杂且需要详细配置时,生成器模式则更为适用。
与抽象工厂模式的关系
- 抽象工厂模式:专注于生成一系列相关对象,但它在对象构造复杂时,其能力也有限。抽象工厂模式通过定义一个接口,使得客户端可以创建相关或依赖对象的家族,而无需明确指定具体类。
- 生成器模式:虽然也用于创建对象,但更侧重于对象的逐步构造和细节配置。生成器模式允许开发者通过不同的生成器来创建具有不同配置和形式的对象。
- 联系与区别:两者都提供了对象的创建方式,但抽象工厂模式更侧重于对象的家族创建,而生成器模式则更侧重于对象的逐步构造和细节配置。此外,抽象工厂模式通常会立即返回产品,而生成器模式则允许在获取产品前执行一些额外的构造步骤。
与其他模式的关系
- 桥接模式:生成器模式可以与桥接模式结合使用,其中主管类负责抽象工作,而各种不同的生成器负责实现工作。这种结合可以使得对象构造更加灵活和可扩展。
- 原型模式:原型模式通过复制现有对象来创建新对象,而生成器模式则通过逐步构造来创建对象。虽然两者在对象创建方式上有所不同,但在某些情况下,它们可以相互补充,共同实现复杂的对象创建需求。
- 单例模式:抽象工厂、生成器和原型模式都可以用单例来实现,以确保对象的唯一性和全局可访问性。然而,这种实现方式并不常见,因为它可能会增加系统的复杂性和维护成本。
7.总结
生成器模式通过将复杂对象的构建过程与表示分离,使得同样的构建过程可以创建不同的表示。它允许逐步构建对象,通过调用生成器对象的方法来添加或修改对象的部件。
相关文章:

设计模式之生成器模式
目录 1.简介 2.结构 3.使用场景 4.实例 5.优缺点 6.与其他模式的关系 7.总结 1.简介 生成器模式(Builder Pattern)是一种创建型设计模式,它允许你通过一步一步构建复杂对象,而不是通过一个包含大量参数的构造函数或方法。该…...

python学opencv|读取图像(三)放大和缩小图像
【1】引言 前序已经学习了常规的图像读取操作和图像保存技巧,相关文章链接为: python学opencv|读取图像-CSDN博客 python学opencv|读取图像(二)保存彩色图像-CSDN博客 今天我们更近一步,学习放大和缩小图像的技巧&…...

1 数据库(上):MySQL的概述和安装、SQL简介、IDEA连接数据库使用图形化界面
文章目录 前言一、数据库相关的概念二、MySQL概述1 MySQL的安装和配置2 MySQL登录、退出(1)mysql -uroot -p1234 或者mysql -uroot -p ---- 登录(2)exit或者quit ---- 退出 3 远程登录服务器上的MySQL命令mysql -hip地址 -P3306 -…...

C++初阶—类与对象(中篇)
第一章:类的6个默认成员函数 如果一个类中什么成员都没有,简称为空类。 空类中真的什么都没有吗?并不是,任何类在什么都不写时,编译器会自动生成以下6个默认成员函数。 默认成员函数:用户没有显式实现&a…...

Leetcode15. 三数之和(HOT100)
链接 一般这种三数之和,四数之和都使用双指针,复杂度最优,次一级可使用哈希表。前者要求有序,后者空间上有花费。 题目: 题目要求答案中不能出现重复vector,比如{-1 1 0}和{-1 0 1}; 这两个…...

Oracle数据库小白备忘
sqlplus相关 导入sql文件 在sqlplus中,导入一个sql文件,是使用或者start。 如当前目录下有一个hello.sql,则可以使用 hello.sql 或者 start hello.sql 来进行导入,功能类似于mysql里面的source。 退出编辑模式 当使用sqlplus…...

DDR4与DDR3服务器内存的关键区别有哪些?
内存作为服务器性能的关键组件之一,已经经历了从DDR3到DDR4的过渡。DDR4内存相较于DDR3在多个方面有所提升,包括速度、带宽、功耗以及数据传输效率等。然而,尽管DDR4内存在性能上占有优势,DDR3内存依然在一些特定场景中得到了广泛…...

Linux: shell: bash: set -x;调试使用
man bash set -x -x After expanding each simple command, for command, case command, select command, or arithmetic for command, display the expanded value of PS4, followed by the command and its expanded arguments or associated word list. 这个可以帮助将变量…...

Hadoop生态圈框架部署 伪集群版(五)- HBase伪分布式部署
文章目录 前言一、Hbase伪分布式部署(手动部署)1. 下载Hbase2. 上传安装包3. 解压HBase安装包4. 配置HBase配置文件4.1 修改hbase-env.sh配置文件4.2 修改hbase-site.xml配置文件4.3 修改regionservers配置文件4.4 删除hbase中slf4j-reload4j-1.7.33.jar…...

自定义指令,全局,局部,注册
让输入框自动获取焦点(每次刷新自动获取焦点) <template><div><h3>自定义指令</h3><input ref"inp" type"text"></div> </template><script> export default {mounted(){this.$refs.inp.focus…...

静坐修心.
文章目录 打坐的历史文化渊源东方的起源与传承西方的接受与演变现代生活中的打坐 盘腿坐对身体的影响促进脊椎健康改善呼吸系统功能增强消化系统机能改善血液循环调节神经系统错误姿势及其他潜在危害 盘腿坐对心理的作用促进内心平静与放松提升自我觉察与内在探索培养专注力与精…...

设计模式c++(一)
文章目录 一、面向对象设计原则二、模版方法三、策略模式四、观察者模式五、装饰模式六、桥模式七、工厂方法_Factory Method八、抽象工厂_Abstract Factory九、原型模式十、构建器_builder十一、单件模式_Singleton十二、享元模式_Flyweight 一、面向对象设计原则 设计模式的…...

核密度估计——从直方图到核密度(核函数)估计_带宽选择
参考 核密度估计(KDE)原理及实现-CSDN博客 机器学习算法(二十一):核密度估计 Kernel Density Estimation(KDE)_算法_意念回复-GitCode 开源社区 引言 在统计学中,概率密度估计是一种重要的方法࿰…...

Vant UI Axure移动端元件库:提升移动端原型设计效率
UI框架的选择对于提升开发效率和用户体验至关重要。Vant UI,作为一款基于Vue.js的轻量、可靠的移动端组件库,自2017年开源以来,凭借其丰富的组件库、良好的性能以及广泛的兼容性,在移动端开发领域崭露头角,赢得了众多开…...

如何用 JavaScript 操作 DOM 元素?
如何用 JavaScript 操作 DOM 元素?——结合实际项目代码示例讲解 在前端开发中,DOM(文档对象模型)操作是与页面交互的核心。通过 DOM 操作,开发者可以动态地修改页面内容、响应用户交互、控制样式等。JavaScript 提供…...

【Ubuntu】URDC(Ubuntu远程桌面助手)安装、用法,及莫名其妙进入全黑模式的处理
1、简述 URDC是Ubuntu远程桌面助手的简称。 它可以: 实时显示桌面:URDC支持通过Windows连接至Ubuntu设备(包括x86和ARM架构,例如Jetson系列、树莓派等)的桌面及光标。远程操控双向同步剪切板多客户端连接:同一Ubuntu设备最多可同时被三台Windows客户端连接和操控,适用于…...

ES-DSL查询
term查询 因为精确查询的字段搜是不分词的字段,因此查询的条件也必须是不分词的词条。查询时,用户输入的内容跟自动值完全匹配时才认为符合条件。如果用户输入的内容过多,反而搜索不到数据。 语法说明: // term查询 GET /index…...

npm 设置镜像
要在npm中设置镜像,你可以使用npm config命令。以下是设置npm镜像的步骤: 临时使用淘宝镜像: npm --registry https://registry.npmmirror.com install package-name 永久设置镜像: npm config set registry https://registry…...

SpringMvc完整知识点一
SpringMVC概述 定义 SpringMVC是一种基于Java实现MVC设计模型的轻量级Web框架 MVC设计模型:即将应用程序分为三个主要组件:模型(Model)、视图(View)和控制器(Controller)。这种分离…...

STM32G4系列MCU双ADC多通道数据转换的应用
目录 概述 1 STM32Cube配置项目 1.1 基本参数配置 1.1.1 ADC1参数配置 1.1.2 ADC2参数配置 1.2 项目软件架构 2 功能实现 2.1 ADC转换初始化 2.2 ADC数据组包 3 测试函数 3.1 Vofa数据接口 3.2 输入数据 4 测试 4.1 ADC1 通道测试 4.2 ADC2 通道测试 概述 本文…...

【工具】音频文件格式转换工具
找开源资源、下载测试不同库的效果,然后找音频、下载音频、编写代码、测试转换、流程通畅。写一个工具花的时间越来越多了!这个 5 天 这个工具是一个音频文件格式转换工具,支持对 mp3.aac.wav.caf.flac.ircam.mp2.mpeg.oga.opus.pcm.ra.spx.…...

ssl证书过期,nginx更换证书以后仍然显示过期证书
记一次nginx部署异常 今天提示ssl证书过期了,然后重新申请了一个证书 反反复复折腾了一个上午,还更换了好几个平台,发现怎么更换都没用,百度上的解决方法都试过了,发现都没用,证书还是显示的原来那一个&…...

原型模式(Prototype Pattern)——对象克隆、深克隆与浅克隆及适用场景
原型模式(Prototype Pattern)是设计模式中的一种创建型模式,目的是通过复制现有的对象来创建新的对象,而不是通过传统的实例化方式。原型模式常常用于需要创建大量类似对象的场景,可以提高性能并减少资源的消耗。下面将…...

从工标网网站解析标准信息
import requests from bs4 import BeautifulSoup 将标准搜索关键词转化成GBK格式,并用%连接转化后16进制,转化成工标网的查询网址url text “GB/T 9755” utf8_encoded_text text.encode(‘GBK’) #print(utf8_encoded_text) hex_representation ‘…...

如何在MySQL中开启死锁日志及查看日志
在数据库的多用户环境中,死锁是一个常见的问题,它可能会影响到数据库的性能和稳定性。MySQL提供了一些工具和命令来帮助我们识别和解决死锁问题。本文将介绍如何在MySQL中开启死锁日志以及如何查看这些日志。 一、为什么需要死锁日志 死锁是指两个或多…...

VCP-CLIP A visual context prompting modelfor zero-shot anomaly segmentation
GitHub - xiaozhen228/VCP-CLIP: (ECCV 2024) VCP-CLIP: A visual context prompting model for zero-shot anomaly segmentation 需要构建正样本,异常样本,以及对应的Mask...

分类算法中的样本不平衡问题及其解决方案
一、样本不平衡问题概述 在机器学习的分类任务中,样本不平衡是指不同类别训练样本数量存在显著差异的现象。这一差异会给模型训练和性能评估带来挑战,尤其在处理少数类样本时,模型可能难以有效学习其特征。 以二分类为例,理想情况…...

博物馆导览系统方案(一)背景需求分析与核心技术实现
维小帮提供多个场所的室内外导航导览方案,如需获取博物馆导览系统解决方案可前往文章最下方获取,如有项目合作及技术交流欢迎私信我们哦~撒花! 一、博物馆导览系统的背景与市场需求 在数字化转型的浪潮中,博物馆作为文化传承和知…...

[创业之路-169]:《BLM战略规划》- 战略洞察 (战略能力中最最核心的能力) - 市场洞察 -1- 看宏观/行业 - 行业:激光器行业的详细分析
目录 一、激光器行业的详细分析 1. 行业总容量分析 2. 行业成长性分析 3. 行业的供需结构 4. 行业的发展阶段与动态S曲线 5. 行业集中度 6. 关键成功因素 二、对深紫外激光器进行如下分析 1、行业总容量分析 2、行业成长性分析 3、行业的供需结构 4、行业的发展阶段…...

抽象工厂模式的理解和实践
在软件开发中,设计模式是解决常见问题的最佳实践。抽象工厂模式是一种创建型设计模式,提供了一种创建一系列相关或相互依赖对象的接口,而无需指定它们的具体类。本文将详细解释抽象工厂模式的概念、结构、优点、缺点,并通过Java代…...