(一)创建型设计模式:3、建造者模式(Builder Pattern)
目录
1、建造者模式含义
2、建造者模式的讲解
3、使用C++实现建造者模式的实例
4、建造者模式的优缺点
5、建造者模式VS工厂模式
1、建造者模式含义
The intent of the Builder design pattern is to separate the construction of a complex object from its representation. By doing so the same construction process can create different representations.
将一个复杂对象的构建过程与其表示分离,使得同样的构建过程可以创建不同的表示。
其实上面这句话本身是有点晦涩难懂,后面在网上看到有人这样说,便留下深刻的印象:
当一个类的构造函数参数个数超过4个,而且这些参数有些是可选的参数,考虑使用构造者模式。
这个解释也可以理解为应用场景,当我们单纯懂得设计模式怎么实现并不重要,重要的是要知道适用于什么场景,这个就得靠一些经验和思考了。
2、建造者模式的讲解
从上面的UML可以看出,建造者模式涉及到以下四个角色的概念:
(1)抽象建造者角色:提供一个接口,规范产品对象的建造,一般由子类实现。一般来说,产品的组成部分数与建造方法数相同,即有多少组成部分,就有多少个建造方法。
(2)具体建造者角色:该角色实现了抽象建造者抽象建造者接口,主要是实现所有声明的方法以及返回建造好的产品实例。
(3)导演者角色:负责调用具体建造者按照顺序建造产品。导演者只负责调度,真正执行的是具体建造者角色。
(4)产品角色:该角色是建造的复杂对象,提供基本方法。
3、使用C++实现建造者模式的实例
#include <iostream>
#include <string>// 产品类
class Product {
public:void setPartA(const std::string& partA) {m_partA = partA;}void setPartB(const std::string& partB) {m_partB = partB;}void setPartC(const std::string& partC) {m_partC = partC;}void show() const {std::cout << "Product Parts: " << m_partA << ", " << m_partB << ", " << m_partC << std::endl;}private:std::string m_partA;std::string m_partB;std::string m_partC;
};// 抽象建造者类
class Builder {
public:virtual void buildPartA() = 0;virtual void buildPartB() = 0;virtual void buildPartC() = 0;virtual Product* getResult() = 0;
};// 具体建造者类
class ConcreteBuilder : public Builder {
public:void buildPartA() override {m_product->setPartA("Part A");}void buildPartB() override {m_product->setPartB("Part B");}void buildPartC() override {m_product->setPartC("Part C");}Product* getResult() override {return m_product;}private:Product* m_product = new Product();
};// 指挥者类
class Director {
public:void construct(Builder* builder) {builder->buildPartA();builder->buildPartB();builder->buildPartC();}
};int main() {Director director;ConcreteBuilder builder;director.construct(&builder);Product* product = builder.getResult();product->show();delete product;return 0;
}
在上述示例中,我们定义了一个产品类(Product),它有三个部分(Part A、Part B、Part C)。然后,我们定义了一个抽象建造者类(Builder),其中包含了构建产品各个部分的纯虚函数。接着,我们实现了具体的建造者类(ConcreteBuilder),它实现了抽象建造者类的纯虚函数,并负责构建产品对象。最后,我们定义了一个指挥者类(Director),它负责调用建造者的方法来构建产品。
在主函数中,我们创建了一个具体的建造者对象,并将其传递给指挥者对象。指挥者根据具体的建造者对象来构建产品,最终得到一个完整的产品对象。我们可以通过产品对象的show()方法来展示产品的各个部分。
这就是一个简单的建造者模式的C++源码示例
4、建造者模式的优缺点
(1)优点:
1)分离构建过程和表示:建造者模式可以将一个复杂对象的构建过程与其表示分离,使得同样的构建过程可以创建不同的表示形式。这样可以提高代码的灵活性和可维护性。
2)更好的封装性:通过建造者模式,可以将对象的构建过程封装在具体的建造者类中,客户端只需要与指挥者进行交互,无需关心具体的构建细节。这样可以隐藏对象的创建过程,提供更好的封装性。
3)可以控制构建过程:建造者模式允许你逐步构建对象,并在每个步骤中进行必要的操作、检查或验证。这样可以更加灵活地控制对象的构建过程,满足不同的需求。
4)创建不同表示形式的对象:通过定义不同的建造者和指挥者,可以根据需求定制不同的构建过程,创建不同的产品表示形式。这样可以提供更多的选择和灵活性。
(2)缺点:
1)增加了代码量:使用建造者模式会增加额外的类和接口,从而增加了代码量。如果对象的构建过程比较简单,使用建造者模式可能会显得过于繁琐。
2)增加了系统复杂性:引入建造者模式会增加系统的复杂性,因为需要定义多个类和接口,并且需要协调指挥者和建造者之间的关系。这可能会增加理解和维护的难度。
3)不适用于创建简单对象:如果对象的构建过程比较简单,只有少量的步骤或参数,使用建造者模式可能会显得过于繁琐。此时,直接使用简单工厂或工厂方法模式可能更加合适。
总的来说,建造者模式通过分离构建过程和表示,提供了更好的封装性和灵活性,可以控制构建过程并创建不同表示形式的对象。然而,它也增加了代码量和系统复杂性,不适用于创建简单对象。
5、建造者模式VS工厂模式
建造者模式和工厂模式是两种常见的创建型设计模式,它们有以下几点区别:
(1)目的不同:工厂模式关注的是创建对象的过程,将对象的创建逻辑封装在一个工厂类中,通过工厂类来创建具体的对象。而建造者模式关注的是创建复杂对象的过程,将对象的构建过程与其表示分离,通过指挥者和建造者来逐步构建对象。
(2)对象复杂度不同:工厂模式适用于创建简单对象,通常只需要一两个步骤即可完成对象的创建。而建造者模式适用于创建复杂对象,对象的构建过程需要多个步骤,并且可以根据需求定制不同的构建过程。
(3)调用方式不同:工厂模式通过调用工厂类的方法来创建对象,客户端直接与工厂类交互。而建造者模式通过指挥者来控制建造者的构建过程,客户端只需要与指挥者进行交互,无需直接与建造者类交互。
(4)灵活性不同:工厂模式相对较为灵活,可以根据需要扩展和添加新的产品类型,只需要添加对应的具体产品和工厂类即可。而建造者模式相对更加灵活,可以根据需要定制不同的构建过程,创建不同的产品表示形式。
总的来说,工厂模式适用于创建简单对象,将对象的创建过程封装在工厂类中;而建造者模式适用于创建复杂对象,通过指挥者和建造者来分步构建对象。
相关文章:

(一)创建型设计模式:3、建造者模式(Builder Pattern)
目录 1、建造者模式含义 2、建造者模式的讲解 3、使用C实现建造者模式的实例 4、建造者模式的优缺点 5、建造者模式VS工厂模式 1、建造者模式含义 The intent of the Builder design pattern is to separate the construction of a complex object from its representatio…...

指针进阶大冒险:解锁C语言中的奇妙世界!
目录 引言 第一阶段:🔍 独特的字符指针 什么是字符指针? 字符指针的用途 演示:使用字符指针拷贝字符串 字符指针与字符串常量 小试牛刀 第二阶段:🎯 玩转指针数组 指针数组是什么? 指针…...

2.0 Maven基础
1. Maven概述 Maven概念 Apache Maven是一个软件项目管理工具,将项目开发和管理过程抽象程一个项目对象模型(POM,Project Object Model)。 Maven作用 项目构建 提供标准的、跨平台的自动化项目构建方式。 依赖管理 方便快捷…...

在Linux虚拟机内配置nginx以及docker
目录 1、nginx源码包编译以及安装依赖 1、配置安装所需的编译环境 2、安装函数库(pcre、zlib、openssl) 2、安装nginx 1、获取源码包 2、解压编译 3、启动nginx服务 1、关闭防火墙 2、运行nginx 3、使用本地浏览器进行验证 3、安装docker 1、…...

数据结构-带头双向循环链表的实现
前言 带头双向循环链表是一种重要的数据结构,它的结构是很完美的,它弥补了单链表的许多不足,让我们一起来了解一下它是如何实现的吧! 1.节点的结构 它的节点中存储着数据和两个指针,一个指针_prev用来记录前一个节点…...

android Ndk Jni动态注册方式以及静态注册
目录 一.静态注册方式 二.动态注册方式 三.源代码 一.静态注册方式 1.项目名\app\src\main下新建一个jni目录 2.在jni目录下,再新建一个Android.mk文件 写入以下配置 LOCAL_PATH := $(call my-dir)//获取当前Android.mk所在目录 inclu...

MySQL中的索引
1.2.MySQL中的索引 InnoDB存储引擎支持以下几种常见的索引:B树索引、全文索引、哈希索引,其中比较关键的是B树索引 1.2.1.B树索引 InnoDB中的索引自然也是按照B树来组织的,前面我们说过B树的叶子节点用来放数据的,但是放什么数…...

idea中如何处理飘红提示
idea中如何处理飘红提示 在写sql时,总是会提示各种错误 查找资料,大部分都是说关提示,这里把错误提示选择为None即可 关掉以后,也确实不显示任何提示了,但总有一种掩耳盗铃的感觉 这个sms表明明存在,但是还…...
Elasticsearch使用中出现的错误
Elasticsearch使用中出现的错误 1、分页查询异常 在分页的过程中出现了一个问题是当查询的数据超过10000条的时候报了异常: from size must be less than or equal to: [10000]这个问题最快捷的解决方式是增大窗口大小: curl -XPUT http://127.0.0.…...

【IMX6ULL驱动开发学习】01.编写第一个hello驱动+自动创建设备节点(不涉及硬件操作)
目录 一、驱动程序编写流程 二、代码编写 2.1 驱动程序hello_drv.c 2.2 测试程序 2.3 编写驱动程序的Makefile 三、上机实验 3.1 NFS 挂载 3.2 测试示例 一、驱动程序编写流程 构造file_operations结构体 在里面填充open/read/write/ioctl成员 注册file_operations结…...

决策规划仿真平台搭建
决策规划仿真平台搭建 自动驾驶决策规划算法第二章第一节 决策规划仿真平台搭建 这部分的主要难点在于多个软件的连通与适配,环境的搭建总是折磨人的,主要是 4 个软件,各软件版本如下 Visual Studio2017PreScan8.5.0CarSim2019.0MATLAB2019b…...
计算图像哈希SHA-512
1、MATLAB实现 计算图像哈希值SHA-512,在文献[1]提到的算法如下: % Example Code: Create an MD5 crypto-hash of an arbitrary string, "str" % Main class of interest: System.Security.Cryptography.HashAlgorithm% Example String to hash with MD5 %…...

Android之消除APP图标的白色边框
有问题的效果: 解决方案: 第一步:app右键—>new—>Image Asset 第二步:上传Logo图标,选择每种分辨率,预览看效果,选择Resize,可以微调 第三步:点击 Nextÿ…...

java线程的优先级、守护线程的概念
1.线程的调度 抢占式调度 非抢占式调度 1.1 抢占式调度 优先级越高,抢到cpu的概率越高 1.2 守护线程 守护线程,非守护线程。当其他的非守护线程执行完毕以后,守护线程会陆续结束。 守护线程的应用场景...
asp.net core 6.0 efcore +sqlserver增删改查的demo
asp.net core 6.0 efcore sqlserver增删改查的demo 下面是一个使用ASP.NET Core 5.0和Entity Framework Core进行增删改查操作的示例。 首先,创建一个空的ASP.NET Core 6.0 Web应用程序项目。 然后,安装以下NuGet包: Microsoft.EntityFra…...

HC32L110B6芯片测试
到货之后,直观上感觉的确很小,小包装盒里面还装了说明书。 下载器单独在一个盒里面,但是这个T-U2T没用上,还是用的STLINK。 开发之前先去网上找了一些别人遇到的坑,的确不少。 涉及的方面也是挺全的,供电、…...
关于我乱删注册表导致电脑没有声音这件事
之前因为想彻底删除迅雷,照着网上进入注册表一顿乱删,也忘记删了啥,反正把一顿xmp的文件,和搜索出来迅雷的全删了。结果迅雷确实没了,被带走的还有电脑的声音。 很离谱,就试过了所有方法都没用,…...
Linux 命令 su 和 sudo 的区别
之前一直对 su 和 sudo 这两个命令犯迷糊,最近专门搜了这方面的资料,总算是把两者的关系以及用法搞清楚了,这篇文章来系统总结一下。 1. 准备工作 因为本篇博客中涉及到用户切换,所以我需要提前准备好几个测试用户,方…...
微信小程序:Mobx的使用指南
简要 微信小程序中有时需要进行全局状态管理,这个时候就需要用到Mobx.下面我们来看一下在小程序中是如何使用Mobx的 安装 pnpm i mobx-miniprogram4.13.2 mobx-miniprogram-bindings1.2.1 或 npm i mobx-miniprogram4.13.2 mobx-miniprogram-bindings1.2.1 或 yarn…...

【Spring Boot】Spring Boot项目的创建和文件配置
目录 一、为什么要学Spring Boot 1、Spring Boot的优点 二、创建Spring Boot项目 1、创建项目之前的准备工作 2、创建Spring Boot项目 3、项目目录的介绍 4、安装Spring Boot快速添加依赖的插件 5、在项目中写一个helloworld 三、Spring Boot的配置文件 1、配置文件的…...

利用最小二乘法找圆心和半径
#include <iostream> #include <vector> #include <cmath> #include <Eigen/Dense> // 需安装Eigen库用于矩阵运算 // 定义点结构 struct Point { double x, y; Point(double x_, double y_) : x(x_), y(y_) {} }; // 最小二乘法求圆心和半径 …...

【Axure高保真原型】引导弹窗
今天和大家中分享引导弹窗的原型模板,载入页面后,会显示引导弹窗,适用于引导用户使用页面,点击完成后,会显示下一个引导弹窗,直至最后一个引导弹窗完成后进入首页。具体效果可以点击下方视频观看或打开下方…...
生成xcframework
打包 XCFramework 的方法 XCFramework 是苹果推出的一种多平台二进制分发格式,可以包含多个架构和平台的代码。打包 XCFramework 通常用于分发库或框架。 使用 Xcode 命令行工具打包 通过 xcodebuild 命令可以打包 XCFramework。确保项目已经配置好需要支持的平台…...
React Native 导航系统实战(React Navigation)
导航系统实战(React Navigation) React Navigation 是 React Native 应用中最常用的导航库之一,它提供了多种导航模式,如堆栈导航(Stack Navigator)、标签导航(Tab Navigator)和抽屉…...
day52 ResNet18 CBAM
在深度学习的旅程中,我们不断探索如何提升模型的性能。今天,我将分享我在 ResNet18 模型中插入 CBAM(Convolutional Block Attention Module)模块,并采用分阶段微调策略的实践过程。通过这个过程,我不仅提升…...

蓝牙 BLE 扫描面试题大全(2):进阶面试题与实战演练
前文覆盖了 BLE 扫描的基础概念与经典问题蓝牙 BLE 扫描面试题大全(1):从基础到实战的深度解析-CSDN博客,但实际面试中,企业更关注候选人对复杂场景的应对能力(如多设备并发扫描、低功耗与高发现率的平衡)和前沿技术的…...

多模态大语言模型arxiv论文略读(108)
CROME: Cross-Modal Adapters for Efficient Multimodal LLM ➡️ 论文标题:CROME: Cross-Modal Adapters for Efficient Multimodal LLM ➡️ 论文作者:Sayna Ebrahimi, Sercan O. Arik, Tejas Nama, Tomas Pfister ➡️ 研究机构: Google Cloud AI Re…...
C++.OpenGL (20/64)混合(Blending)
混合(Blending) 透明效果核心原理 #mermaid-svg-SWG0UzVfJms7Sm3e {font-family:"trebuchet ms",verdana,arial,sans-serif;font-size:16px;fill:#333;}#mermaid-svg-SWG0UzVfJms7Sm3e .error-icon{fill:#552222;}#mermaid-svg-SWG0UzVfJms7Sm3e .error-text{fill…...
Python网页自动化Selenium中文文档
1. 安装 1.1. 安装 Selenium Python bindings 提供了一个简单的API,让你使用Selenium WebDriver来编写功能/校验测试。 通过Selenium Python的API,你可以非常直观的使用Selenium WebDriver的所有功能。 Selenium Python bindings 使用非常简洁方便的A…...

react菜单,动态绑定点击事件,菜单分离出去单独的js文件,Ant框架
1、菜单文件treeTop.js // 顶部菜单 import { AppstoreOutlined, SettingOutlined } from ant-design/icons; // 定义菜单项数据 const treeTop [{label: Docker管理,key: 1,icon: <AppstoreOutlined />,url:"/docker/index"},{label: 权限管理,key: 2,icon:…...