9.建造者模式 (Builder Pattern)
定义
建造者模式(Builder Pattern)是一种创建型设计模式,旨在将复杂对象的构建过程与它的表示分离,使得同样的构建过程可以创建不同的表示。该模式的核心思想是通过一步步地构建一个复杂的对象,每个步骤独立且可扩展,并且最终的产品(对象)可以通过不同的构建步骤得到不同的结果。
结构:
建造者模式通常由以下几个角色组成:
Product(产品):最终构建出来的复杂对象。
Builder(建造者):抽象建造者,定义了构建各个部件的接口,通常会有一个返回产品的方法。
ConcreteBuilder(具体建造者):实现了 Builder 接口,负责构建具体的部件,并最终生成产品。
Director(指挥者):负责指导建造者进行构建,按照一定的顺序来调用建造者的方法,最终获取产品。
Client(客户端):使用 Director 和 Builder 来构建产品。
类的设计分析:
1. House(产品类)
class House {// 复杂对象的定义,包含房屋的不同部分
};House 类表示最终要构建的复杂对象。
在这个例子中,它代表一个房子,包含房子的多个部分,如墙壁、屋顶、地板等。
2. HouseBuilder(抽象建造者)
class HouseBuilder {
public:House* GetResult() {return pHouse;}virtual ~HouseBuilder() {}
protected:House* pHouse;virtual void BuildPart1() = 0;virtual void BuildPart2() = 0;virtual void BuildPart3() = 0;virtual void BuildPart4() = 0;virtual void BuildPart5() = 0;
};
- HouseBuilder 类 是一个抽象建造者,它定义了建造过程中的各个步骤,如 BuildPart1 到 BuildPart5 方法。这些方法是用来构建房子的不同部分的。
- GetResult() 方法返回最终构建的产品(House 对象)。
- HouseBuilder 中的具体部分构建由继承类实现。
3. StoneHouse(具体产品类)
class StoneHouse : public House {// 石头房子可能有一些特定的功能
};
4. StoneHouseBuilder(具体建造者)
class StoneHouseBuilder : public HouseBuilder {
protected:virtual void BuildPart1() {// 构建房子的第一个部分(例如,地基)}virtual void BuildPart2() {// 构建房子的第二个部分(例如,墙壁)}virtual void BuildPart3() {// 构建房子的第三个部分(例如,屋顶)}virtual void BuildPart4() {// 构建房子的第四个部分(例如,窗户)}virtual void BuildPart5() {// 构建房子的第五个部分(例如,门)}
};
- StoneHouseBuilder 类 是 HouseBuilder 的具体实现类,负责实现如何一步步构建 StoneHouse(石头房子)的各个部分。每个 BuildPart 方法的实现可能会根据不同的房屋类型进行不同的构建。
5. HouseDirector(指挥者)
class HouseDirector {
public:HouseBuilder* pHouseBuilder;HouseDirector(HouseBuilder* pHouseBuilder) {this->pHouseBuilder = pHouseBuilder;}House* Construct() {pHouseBuilder->BuildPart1();for (int i = 0; i < 4; i++) {pHouseBuilder->BuildPart2();}bool flag = pHouseBuilder->BuildPart3();if (flag) {pHouseBuilder->BuildPart4();}pHouseBuilder->BuildPart5();return pHouseBuilder->GetResult();}
};
- HouseDirector 类 是指挥者角色,负责使用建造者 HouseBuilder 来构建产品(房子)。它定义了房子的建造过程,按照一定顺序调用建造者的各个方法,最终返回建造好的 House 产品。
6. Client(客户端)
- 客户端负责创建具体的建造者(如 StoneHouseBuilder)和指挥者(HouseDirector),并通过指挥者来完成房子的建造。
实现步骤
1.定义产品:首先定义 House 类,它包含房子各个部分的数据结构。
2.创建抽象建造者:定义一个 HouseBuilder 类,包含构建各个部分的抽象方法,以及返回最终产品的方法 GetResult。
3.创建具体建造者:实现 HouseBuilder 类的具体子类(如 StoneHouseBuilder),提供每个构建步骤的具体实现。
4.创建指挥者:定义一个 HouseDirector 类,它使用具体建造者按照顺序来构建房子。
5.客户端调用:客户端可以创建具体的建造者和指挥者,并通过指挥者来构建房子。
调用示例:
int main() {// 创建具体的建造者StoneHouseBuilder* builder = new StoneHouseBuilder();// 创建指挥者并传入建造者HouseDirector* director = new HouseDirector(builder);// 开始构建房子House* house = director->Construct();// 输出构建的结果std::cout << "House is built!" << std::endl;delete builder;delete director;delete house;return 0;
}
什么场景使用 Builder Pattern
建造者模式适用于以下几种场景:
复杂对象的创建过程:当一个对象的构建过程非常复杂时(有多个部件或多个构建步骤),可以使用建造者模式将构建过程拆分成多个步骤,使得每个步骤独立,并且支持不同的构建方式。
例如,构建复杂的文件解析器、数据库连接器、UI 界面等。
对象的组成部分不变,但表现形式不同:当构建的对象(如房子)由多个部件组成,但可以有不同的表现形式时,可以使用建造者模式。
例如,构建不同类型的房子(如木房子、石房子等),它们共享相同的构建步骤,但具体实现会有所不同。
需要一步一步构建对象的情况:当构建一个对象需要分多个步骤,且顺序不可随意改变时,建造者模式特别适用。
避免对象构建过程的重复:如果有多个地方需要重复相同的对象构建逻辑,建造者模式可以将构建过程封装在 Builder 类中,避免代码重复。
总结
建造者模式通过分离复杂对象的构建过程和对象的表示,使得构建过程更加灵活,支持多种对象表示方式。在实际开发中,当对象的构建过程繁琐且有多个可选的组成部分时,建造者模式是一种非常有效的设计模式。
相关文章:
9.建造者模式 (Builder Pattern)
定义 建造者模式(Builder Pattern)是一种创建型设计模式,旨在将复杂对象的构建过程与它的表示分离,使得同样的构建过程可以创建不同的表示。该模式的核心思想是通过一步步地构建一个复杂的对象,每个步骤独立且可扩展&…...
OpenCV:特征检测总结
目录 一、什么是特征检测? 二、OpenCV 中的常见特征检测方法 1. Harris 角点检测 2. Shi-Tomasi 角点检测 3. Canny 边缘检测 4. SIFT(尺度不变特征变换) 5. ORB 三、特征检测的应用场景 1. 图像匹配 2. 运动检测 3. 自动驾驶 4.…...
Clion开发STM32时使用stlink下载程序与Debug调试
一、下载程序 先创建一个文件夹: 命名:stlink.cfg 写入以下代码: # choose st-link/j-link/dap-link etc. #adapter driver cmsis-dap #transport select swdsource [find interface/stlink.cfg]transport select hla_swdsource [find target/stm32f4x.…...
电脑开机键一闪一闪打不开
家人们谁懂啊!本来打算愉快地开启游戏时光,或者高效处理工作任务,结果按下电脑开机键后,它就只是一闪一闪的,怎么都打不开。相信不少朋友都遭遇过这种令人崩溃的场景,满心的期待瞬间化为焦急与无奈。电脑在…...
深度学习 Pytorch 基础网络手动搭建与快速实现
为了方便后续练习的展开,我们尝试自己创建一个数据生成器,用于自主生成一些符合某些条件、具备某些特性的数据集。 导入相关的包 # 随机模块 import random# 绘图模块 import matplotlib as mpl import matplotlib.pyplot as plt# 导入numpy import nu…...
Sqli-labs靶场实录(一):Basic Challenges
sqli-labs靶场实录:Basic Challenges sql手注基本流程Less-11.1探测注入点1.2判断字段数1.3判断回显位1.4提取数据库基本信息1.5拖取敏感数据 Less-2Less-3Less-4Less5爆表爆列名 Less6爆库爆表爆列名 Less7猜解数据库长度逐字符爆破数据库名 Less8爆库 Less9爆库 Less10Less11…...
2024最新版Node.js详细安装教程(含npm配置淘宝最新镜像地址)
一:Node.js安装 浏览器中搜索Nodejs,或直接用网址:Node.js — 在任何地方运行 JavaScript 建议此处下载长期支持版本(红框内): 开始下载,完成后打开文件: 进入安装界面,在此处勾选,再点击n…...
RK3568使用QT搭建TCP服务器和客户端
文章目录 一、让RK3568开发板先连接上wifi二、客户端代码1. `widget.h` 文件2. `widget.cpp` 文件**详细讲解**1. **`Widget` 类构造函数 (`Widget::Widget`)**2. **UI 布局 (`setupUI`)**3. **连接按钮的槽函数 (`onConnectClicked`)**4. **发送消息按钮的槽函数 (`onSendMess…...
Android学习20 -- 手搓App2(Gradle)
1 前言 昨天写了一个完全手搓的:Android学习19 -- 手搓App-CSDN博客 后面谷歌说不要用aapt,d8这些来搞。其实不想弄Gradle的,不过想着既然开始了,就多看一些。之前写过一篇Gradle,不过是最简单的编译,不涉…...
LeetCode - Google 大模型10题 第2天 Position Embedding(位置编码) 3题
欢迎关注我的CSDN:https://spike.blog.csdn.net/ 本文地址:https://spike.blog.csdn.net/article/details/145454489 在 Transformer 架构中,位置编码(Position Embedding) 是辅助模型理解序列中元素顺序的关键机制。绝对位置编码(Absolute P…...
PostgreSQL 数据库备份与还原
为了安全与数据共享等,创建好的数据库有时候需要备份操作和还原操作。数据库的备份与还原主要是三个命令:pg_dump、pg_dumpall 和 pg_restore 。 其中pg_dump用于备份单个数据库,它支持多种备份格式(SQL、自定义等)&a…...
proxmox通过更多的方式创建虚拟机
概述 作为一名资深运维工程师,我们经常需要在 Proxmox 虚拟化平台上创建和管理虚拟机。本文将介绍三种不同的方式在 Proxmox 上创建 Ubuntu 虚拟机: 通过 Proxmox 命令创建虚拟机通过 Shell 脚本自动化创建虚拟机使用 Proxmox API 创建虚拟机 每种方式…...
WordPress使用(2)
上一篇文章讲述了WordPress的基本安装,主要是docker方式的处理。本文章主要介绍WordPress安装后的其他设置。 1. 安装后设置 安装后碰到的第一个需求就是安装一个合适的主题,但WordPress默认的上传文件大小是2M,远远无法满足要求࿰…...
git中文件的状态状态切换
文件的状态分类 Git 中文件的状态主要分为以下几种: Untracked(未跟踪) 定义:这些文件从未被 Git 跟踪过,通常是因为它们是新创建的文件,或者被 .gitignore 排除在外。 示例:新创建的文件 new…...
解决php8.3无法加载curl扩展
把它的值更改为扩展存在的目录的绝对路径(扩展存在的目录为有php_xxx.dll存在的目录) extension_dir "e:\serv\php83\ext" 然后从php根目录复制 libssh2.dll 和 libcrypto-*.dll 和 libssl-*.dll 到Apache根目录下的bin目录 重启apache服务即可...
三路排序算法
三路排序算法 引言 排序算法是计算机科学中基础且重要的算法之一。在数据分析和处理中,排序算法的效率直接影响着程序的执行速度和系统的稳定性。本文将深入探讨三路排序算法,包括其原理、实现和应用场景。 一、三路排序算法的原理 三路排序算法是一…...
入行FPGA设计工程师需要提前学习哪些内容?
FPGA作为一种灵活可编程的硬件平台,广泛应用于嵌入式系统、通信、数据处理等领域。很多人选择转行FPGA设计工程师,但对于新手来说,可能在学习过程中会遇到一些迷茫和困惑。为了帮助大家更好地准备,本文将详细介绍入行FPGA设计工程…...
DBASE DBF数据库文件解析
基于Java实现DBase DBF文件的解析和显示 JDK19编译运行,实现了数据库字段和数据解析显示。 首先解析数据库文件头代码 byte bytes[] Files.readAllBytes(Paths.get(file));BinaryBufferArray bis new BinaryBufferArray(bytes);DBF dbf new DBF();dbf.VersionN…...
html基本结构和常见元素
html5文档基本结构 <!DOCTYPE html> <html lang"zh-CN"> <head><meta charset"UTF-8"><title>文档标题</title> </head> <body>文档正文部分 </body> </html> html文档可分为文档头和文档体…...
JAVAweb学习日记(十) Mybatis入门操作
一、介绍 二、快速入门程序 三、入门-数据库连接池 四、入门-lombok工具包...
linux之kylin系统nginx的安装
一、nginx的作用 1.可做高性能的web服务器 直接处理静态资源(HTML/CSS/图片等),响应速度远超传统服务器类似apache支持高并发连接 2.反向代理服务器 隐藏后端服务器IP地址,提高安全性 3.负载均衡服务器 支持多种策略分发流量…...
【Java学习笔记】Arrays类
Arrays 类 1. 导入包:import java.util.Arrays 2. 常用方法一览表 方法描述Arrays.toString()返回数组的字符串形式Arrays.sort()排序(自然排序和定制排序)Arrays.binarySearch()通过二分搜索法进行查找(前提:数组是…...
基于服务器使用 apt 安装、配置 Nginx
🧾 一、查看可安装的 Nginx 版本 首先,你可以运行以下命令查看可用版本: apt-cache madison nginx-core输出示例: nginx-core | 1.18.0-6ubuntu14.6 | http://archive.ubuntu.com/ubuntu focal-updates/main amd64 Packages ng…...
Linux简单的操作
ls ls 查看当前目录 ll 查看详细内容 ls -a 查看所有的内容 ls --help 查看方法文档 pwd pwd 查看当前路径 cd cd 转路径 cd .. 转上一级路径 cd 名 转换路径 …...
postgresql|数据库|只读用户的创建和删除(备忘)
CREATE USER read_only WITH PASSWORD 密码 -- 连接到xxx数据库 \c xxx -- 授予对xxx数据库的只读权限 GRANT CONNECT ON DATABASE xxx TO read_only; GRANT USAGE ON SCHEMA public TO read_only; GRANT SELECT ON ALL TABLES IN SCHEMA public TO read_only; GRANT EXECUTE O…...
使用van-uploader 的UI组件,结合vue2如何实现图片上传组件的封装
以下是基于 vant-ui(适配 Vue2 版本 )实现截图中照片上传预览、删除功能,并封装成可复用组件的完整代码,包含样式和逻辑实现,可直接在 Vue2 项目中使用: 1. 封装的图片上传组件 ImageUploader.vue <te…...
新能源汽车智慧充电桩管理方案:新能源充电桩散热问题及消防安全监管方案
随着新能源汽车的快速普及,充电桩作为核心配套设施,其安全性与可靠性备受关注。然而,在高温、高负荷运行环境下,充电桩的散热问题与消防安全隐患日益凸显,成为制约行业发展的关键瓶颈。 如何通过智慧化管理手段优化散…...
Caliper 配置文件解析:config.yaml
Caliper 是一个区块链性能基准测试工具,用于评估不同区块链平台的性能。下面我将详细解释你提供的 fisco-bcos.json 文件结构,并说明它与 config.yaml 文件的关系。 fisco-bcos.json 文件解析 这个文件是针对 FISCO-BCOS 区块链网络的 Caliper 配置文件,主要包含以下几个部…...
Java面试专项一-准备篇
一、企业简历筛选规则 一般企业的简历筛选流程:首先由HR先筛选一部分简历后,在将简历给到对应的项目负责人后再进行下一步的操作。 HR如何筛选简历 例如:Boss直聘(招聘方平台) 直接按照条件进行筛选 例如:…...
.Net Framework 4/C# 关键字(非常用,持续更新...)
一、is 关键字 is 关键字用于检查对象是否于给定类型兼容,如果兼容将返回 true,如果不兼容则返回 false,在进行类型转换前,可以先使用 is 关键字判断对象是否与指定类型兼容,如果兼容才进行转换,这样的转换是安全的。 例如有:首先创建一个字符串对象,然后将字符串对象隐…...
