(五)趣学设计模式 之 建造者模式!

目录
- 一、 啥是建造者模式?
- 二、 为什么要用建造者模式?
- 三、 建造者模式怎么实现?
- 四、 建造者模式的应用场景
- 五、 建造者模式的优点和缺点
- 六、 总结
🌟我的其他文章也讲解的比较有趣😁,如果喜欢博主的讲解方式,可以多多支持一下,感谢🤗!
🌟了解原型模式请看: (四)趣学设计模式 之 原型模式!
这篇文章带你详细认识一下设计模式中的建造者模式
一、 啥是建造者模式?
建造者模式,就像组装乐高玩具 🧸! 你有一堆零件,想要拼出一个复杂的模型,比如一辆汽车 🚗 或者一栋房子 🏠,但是直接拼太麻烦了,容易出错,而且不同的汽车和房子,拼装步骤可能不一样。 建造者模式就是把组装过程分解成一步一步的,每一步负责一部分,比如安装引擎、安装轮胎、刷油漆等等,每一步都由专门的工人(具体建造者)来完成,最后把所有部分组合起来,就得到了完整的模型!
- 对象创建过程复杂: 就像盖房子 🏠,需要打地基、砌墙、安装门窗、装修等等,一步都不能少,而且顺序也很重要!
- 需要灵活控制对象创建过程: 就像定制汽车 🚗,可以根据自己的喜好选择不同的引擎、轮胎、颜色等等,每个配置都会影响最终的汽车!
- 希望隐藏对象内部的构建细节: 就像吃汉堡 🍔,你只想吃,不想知道它是怎么做的,更不想知道厨师是怎么一步一步把汉堡做出来的!
二、 为什么要用建造者模式?
用建造者模式,好处多多:
- 分工明确: 每个建造者负责一部分,职责清晰,代码更易维护! 就像盖房子,有专门的泥瓦匠砌墙,有专门的木匠安装门窗,每个人都只负责自己的部分,不会互相干扰!
- 灵活定制: 可以根据需要选择不同的建造者,创建不同配置的对象! 就像定制汽车,可以选择不同的引擎、轮胎、颜色等等,最终得到一辆完全符合自己需求的汽车!
- 隐藏细节: 客户端不用关心对象的构建过程,只需要知道最终的结果! 就像吃汉堡,你只需要知道汉堡很好吃,不用关心厨师是怎么一步一步把汉堡做出来的!
- 代码复用: 相同的构建步骤可以被不同的建造者复用! 就像盖房子,不同的房子可能都需要打地基,这个步骤就可以被不同的建造者复用!
三、 建造者模式怎么实现?
建造者模式主要包含以下几个角色:
- 产品(Product): 最终要创建的对象,就像乐高模型、汽车、房子等等!
- 抽象建造者(Builder): 定义了构建产品的接口,就像乐高说明书、汽车设计图纸、房屋设计图纸等等! 它规定了构建产品的各个步骤,但是具体的实现由具体建造者来完成!
- 具体建造者(ConcreteBuilder): 实现了抽象建造者的接口,负责构建产品的各个部分,就像乐高工人、汽车工人、建筑工人等等! 他们按照抽象建造者的规定,一步一步地构建产品!
- 指挥者(Director): 负责安排构建的顺序,就像乐高设计师、汽车设计师、房屋设计师等等! 他们知道构建产品的正确顺序,并指挥具体建造者按照这个顺序来构建产品!
代码示例:
// 1. 产品类 (Product)
class Computer {private String cpu; // CPUprivate String ram; // 内存private String hardDisk; // 硬盘private String graphicsCard; // 显卡// 设置 CPUpublic void setCpu(String cpu) {this.cpu = cpu;}// 设置 内存public void setRam(String ram) {this.ram = ram;}// 设置 硬盘public void setHardDisk(String hardDisk) {this.hardDisk = hardDisk;}// 设置 显卡public void setGraphicsCard(String graphicsCard) {this.graphicsCard = graphicsCard;}// 重写 toString 方法,方便打印电脑信息@Overridepublic String toString() {return "Computer{" +"cpu='" + cpu + '\'' +", ram='" + ram + '\'' +", hardDisk='" + hardDisk + '\'' +", graphicsCard='" + graphicsCard + '\'' +'}';}
}// 2. 抽象建造者 (Builder)
interface ComputerBuilder {void buildCpu(String cpu); // 构建 CPUvoid buildRam(String ram); // 构建 内存void buildHardDisk(String hardDisk); // 构建 硬盘void buildGraphicsCard(String graphicsCard); // 构建 显卡Computer build(); // 返回最终产品
}// 3. 具体建造者 (ConcreteBuilder)
class GamingComputerBuilder implements ComputerBuilder {private Computer computer = new Computer(); // 创建一个电脑对象// 构建 CPU@Overridepublic void buildCpu(String cpu) {computer.setCpu(cpu);}// 构建 内存@Overridepublic void buildRam(String ram) {computer.setRam(ram);}// 构建 硬盘@Overridepublic void buildHardDisk(String hardDisk) {computer.setHardDisk(hardDisk);}// 构建 显卡@Overridepublic void buildGraphicsCard(String graphicsCard) {computer.setGraphicsCard(graphicsCard);}// 返回最终产品@Overridepublic Computer build() {return computer;}
}// 4. 指挥者 (Director)
class ComputerDirector {private ComputerBuilder builder; // 依赖一个 ComputerBuilder// 构造函数,传入一个 ComputerBuilderpublic ComputerDirector(ComputerBuilder builder) {this.builder = builder;}// 构建电脑public Computer construct(String cpu, String ram, String hardDisk, String graphicsCard) {builder.buildCpu(cpu); // 构建 CPUbuilder.buildRam(ram); // 构建 内存builder.buildHardDisk(hardDisk); // 构建 硬盘builder.buildGraphicsCard(graphicsCard); // 构建 显卡return builder.build(); // 返回最终产品}
}// 5. 客户端使用
public class Client {public static void main(String[] args) {// 创建具体建造者GamingComputerBuilder gamingComputerBuilder = new GamingComputerBuilder();// 创建指挥者ComputerDirector computerDirector = new ComputerDirector(gamingComputerBuilder);// 构建电脑Computer gamingComputer = computerDirector.construct("Intel i9", "32GB", "1TB SSD", "Nvidia RTX 3080");// 打印电脑信息System.out.println("游戏电脑: " + gamingComputer);}
}
代码解释:
Computer:产品类,表示电脑。 就像乐高模型,是最终要组装完成的东西!ComputerBuilder:抽象建造者,定义了构建电脑的接口。 就像乐高说明书,规定了组装电脑的各个步骤!GamingComputerBuilder:具体建造者,实现了ComputerBuilder接口,负责构建游戏电脑。 就像乐高工人,按照说明书一步一步地组装电脑!ComputerDirector:指挥者,负责安排构建的顺序。 就像乐高设计师,知道组装电脑的正确顺序,并指挥工人按照这个顺序来组装电脑!
输出结果:
游戏电脑: Computer{cpu='Intel i9', ram='32GB', hardDisk='1TB SSD', graphicsCard='Nvidia RTX 3080'}
分析:
客户端只需要告诉指挥者需要什么配置的电脑,指挥者会安排具体建造者一步一步地构建电脑,最后返回完整的电脑对象。 客户端不需要关心电脑是怎么一步一步组装起来的,只需要知道最终的结果!
四、 建造者模式的应用场景
- 创建复杂的对象: 就像创建汽车 🚗、房子 🏠、飞机 ✈️ 等等,需要多个步骤才能完成,而且每个步骤都很复杂!
- 需要灵活控制对象创建过程: 就像定制家具 🪑,可以根据自己的喜好选择不同的材料、颜色和尺寸,最终得到一件完全符合自己需求的家具!
- 需要隐藏对象内部的构建细节: 就像制作蛋糕 🎂,你只想吃,不想知道它是怎么做的,更不想知道厨师是怎么一步一步把蛋糕做出来的!
- 需要创建不同表示的对象: 就像创建不同风格的房子 🏘️,可以使用不同的建造者来创建,比如现代风格的房子、古典风格的房子等等!
五、 建造者模式的优点和缺点
优点:
- 分工明确: 每个建造者负责一部分,职责清晰,代码更易维护! 就像一个团队,每个人都只负责自己的部分,不会互相干扰,提高了工作效率!
- 灵活定制: 可以根据需要选择不同的建造者,创建不同配置的对象! 就像定制汽车,可以选择不同的引擎、轮胎、颜色等等,最终得到一辆完全符合自己需求的汽车!
- 隐藏细节: 客户端不用关心对象的构建过程,只需要知道最终的结果! 就像吃汉堡,你只需要知道汉堡很好吃,不用关心厨师是怎么一步一步把汉堡做出来的!
- 代码复用: 相同的构建步骤可以被不同的建造者复用! 就像盖房子,不同的房子可能都需要打地基,这个步骤就可以被不同的建造者复用,减少了代码的重复!
- 易于扩展: 可以很容易地添加新的建造者,来创建新的对象类型! 就像乐高玩具,可以不断推出新的模型,只需要添加新的乐高说明书和乐高工人即可!
缺点:
- 代码复杂: 需要创建多个类,代码量比较大! 就像一个团队,需要更多的人员,增加了管理的复杂性!
- 抽象性高: 理解起来比较抽象,需要一定的设计经验! 就像学习乐高说明书,需要一定的空间想象能力!
- 修改困难: 如果需要修改产品的内部结构,可能需要修改多个类! 就像修改乐高模型,可能需要修改乐高说明书和乐高零件!
六、 总结
- 建造者模式就像组装乐高玩具,把复杂的对象创建过程分解成一步一步的!
- 适用于对象创建过程复杂、需要灵活控制对象创建过程、希望隐藏对象内部的构建细节的场景!
- 主要包含产品、抽象建造者、具体建造者和指挥者四个角色!
- 优点是分工明确、灵活定制、隐藏细节、代码复用、易于扩展!
- 缺点是代码复杂、抽象性高、修改困难!
希望这篇文章能让你彻底理解建造者模式! 👍
相关文章:
(五)趣学设计模式 之 建造者模式!
目录 一、 啥是建造者模式?二、 为什么要用建造者模式?三、 建造者模式怎么实现?四、 建造者模式的应用场景五、 建造者模式的优点和缺点六、 总结 🌟我的其他文章也讲解的比较有趣😁,如果喜欢博主的讲解方…...
香橙派/树莓派 利用Wiring库 使用GPIO模拟PWM
香橙派或者树莓派 等开发板,本身带有硬件PWM,比如香橙派3 lts版,但是这个引脚不符合我的项目需求,我需要外接一个电机,在检测到人脸的时候 转动,但是这个硬件引脚,只要上电就开始输出pwm 信号,导…...
全面收集中间件Exporter适配:从Redis到ActiveMQ,掌握监控数据采集的最佳实践
#作者:任少近 文章目录 说明:一 Redis的适配exporter版1.1 Redis的exporter源码版本1.2 Redis的exporter的releases版1.3 Redis_exporter版本选择理由1.4 Redis_exporter docer镜像 二 Zookeeper的适配exporter版2.1 Zookeeper的exporter源码版本2.2 Zo…...
机器学习数学通关指南——链式法则
前言 本文隶属于专栏《机器学习数学通关指南》,该专栏为笔者原创,引用请注明来源,不足和错误之处请在评论区帮忙指出,谢谢! 本专栏目录结构和参考文献请见《机器学习数学通关指南》 正文 一、定义与公式 链式法则&a…...
JavaScript函数-arguments的使用
在JavaScript编程语言中,函数是构建复杂逻辑和实现代码复用的关键组件。虽然现代JavaScript(尤其是ES6及之后版本)提供了更多灵活的方式来处理函数参数(如剩余参数、默认参数等),但arguments对象仍然是一个…...
千峰React:函数组件使用(2)
前面写了三千字没保存,恨! 批量渲染 function App() {const list [{id:0,text:aaaa},{id:1,text:bbbb},{id:2,text:cccc}]// for (let i 0; i < list.length; i) {// list[i] <li>{list[i]}</li>// }return (<div><…...
DPVS-3: 双臂负载均衡测试
测试拓扑 双臂模式, 使用两个网卡,一个对外,一个对内。 Client host是物理机, RS host都是虚拟机。 LB host是物理机,两个CX5网卡分别在两个子网。 配置文件 用dpvs.conf.sample作为双臂配置文件,其中…...
2016年下半年试题二:论软件设计模式及其应用
论文库链接:系统架构设计师论文 论文题目 软件设计模式(Software DesignPatter)是一套被反复使用的、多数人知晓的、经过分类编目的代码设计经验的总结。使用设计模式是为了重用代码以提高编码效率增加代码的可理解性、保证代码的可靠性。软件设计模式是软件开发中的…...
深入理解 SQL 中的 DATEDIFF 函数
深入理解 SQL 中的 DATEDIFF 函数 DATEDIFF 函数在 SQL 中是一个用于计算两个日期之间差值的重要工具。不同数据库实现了不同版本的 DATEDIFF,它们在功能和语法上有所不同。本文将详细解析 DATEDIFF 的用法、数据库间差异、复杂场景中的应用,以及替代方…...
【第二节】C++设计模式(创建型模式)-抽象工厂模式
目录 引言 一、抽象工厂模式概述 二、抽象工厂模式的应用 三、抽象工厂模式的适用场景 四、抽象工厂模式的优缺点 五、总结 引言 抽象工厂设计模式是一种创建型设计模式,旨在解决一系列相互依赖对象的创建问题。它与工厂方法模式密切相关,但在应用…...
【学习资料】嵌入式人工智能Embedded AI
图片来源: Embedded Artificial Intelligence for Business Purposes | DAC.digital 随着AI在设备端的应用,我们看到越来越多的可穿戴设备出现以及自动驾驶汽车的发展,可以看到嵌入式人工智能是新的发展方向。我为大家介绍嵌入式人工智能的…...
【Python爬虫(60)】解锁社交媒体数据宝藏:Python爬虫实战攻略
【Python爬虫】专栏简介:本专栏是 Python 爬虫领域的集大成之作,共 100 章节。从 Python 基础语法、爬虫入门知识讲起,深入探讨反爬虫、多线程、分布式等进阶技术。以大量实例为支撑,覆盖网页、图片、音频等各类数据爬取ÿ…...
C++ 继承,多态
看前须知: 本篇博客是作者听课时的笔记,不喜勿喷,若有疑问可以评论区一起讨论。 继承 定义: 继承机制是⾯向对象程序设计使代码可以复⽤的最重要的⼿段,它允许我们在保持原有 类特性的基础上进⾏扩展,增…...
Java中的Stream API:从入门到实战
引言 在现代Java开发中,Stream API 是处理集合数据的强大工具。它不仅让代码更加简洁易读,还能通过并行处理提升性能。本文将带你从基础概念入手,逐步深入Stream API的使用,并通过实战案例展示其强大功能。 1. 什么是Stream API…...
QPainter绘制3D 饼状图
先展示图片 核心代码如下: pie.h #ifndef Q3DPIE_H #define Q3DPIE_H#include <QtGui/QPen> #include <QtGui/QBrush>class Pie { public:double value; QBrush brush; QString description; double percentValue;QString p…...
【FAQ】HarmonyOS SDK 闭源开放能力 —Live View Kit (1)
1.问题描述: 客户端创建实况窗后,通过Push kit更新实况窗内容,这个过程是自动更新的还是客户端解析push消息数据后填充数据更新?客户端除了接入Push kit和创建实况窗还需要做什么工作? 解决方案: 通过Pu…...
数据治理与管理
引入 上一篇我们聊了数仓架构设计,它是企业构建数据中台的基石。其本质就是构建一个可靠易用的架构,可以借此将原始数据汇聚、处理,最终转换成可消费使用的数据资源。 在拥有数据资源以后,我们就需要考虑如何利用它,为企业创造价值,让它变成企业的资产而不是负担。也就…...
什么是HTTP/2协议?NGINX如何支持HTTP/2并提升网站性能?
HTTP/2是一种用于在Web浏览器和服务器之间进行通信的协议,旨在提高网站性能和加载速度。它是HTTP/1.1的继任者,引入了许多优化和改进,以适应现代Web应用的需求。HTTP/2的主要目标是减少延迟、提高效率,以及更好地支持并发请求。 …...
安全运维,等保测试常见解决问题。
1. 未配置口令复杂度策略。 # 配置密码安全策略 # vi /etc/pam.d/system-auth # local_users_only 只允许本机用户。 # retry 3 最多重复尝试3次。 # minlen12 最小长度为12个字符。 # dcredit-1 至少需要1个数字字符。 # ucredit-1 至少需要1个大…...
jmeter接口测试(二)
一、不同参数类型的接口测试 二、动态参数接口处理 随机数 工具——>函数助手对话框(Random 1000-10000之间的随机数 变量名为rdn)如下图所示 把上图生成的函数字符串复制到想要使用的地方如下图 三、断言 1、状态断言,200 不能证明…...
XCTF-web-easyupload
试了试php,php7,pht,phtml等,都没有用 尝试.user.ini 抓包修改将.user.ini修改为jpg图片 在上传一个123.jpg 用蚁剑连接,得到flag...
反向工程与模型迁移:打造未来商品详情API的可持续创新体系
在电商行业蓬勃发展的当下,商品详情API作为连接电商平台与开发者、商家及用户的关键纽带,其重要性日益凸显。传统商品详情API主要聚焦于商品基本信息(如名称、价格、库存等)的获取与展示,已难以满足市场对个性化、智能…...
前端倒计时误差!
提示:记录工作中遇到的需求及解决办法 文章目录 前言一、误差从何而来?二、五大解决方案1. 动态校准法(基础版)2. Web Worker 计时3. 服务器时间同步4. Performance API 高精度计时5. 页面可见性API优化三、生产环境最佳实践四、终极解决方案架构前言 前几天听说公司某个项…...
【网络安全产品大调研系列】2. 体验漏洞扫描
前言 2023 年漏洞扫描服务市场规模预计为 3.06(十亿美元)。漏洞扫描服务市场行业预计将从 2024 年的 3.48(十亿美元)增长到 2032 年的 9.54(十亿美元)。预测期内漏洞扫描服务市场 CAGR(增长率&…...
HBuilderX安装(uni-app和小程序开发)
下载HBuilderX 访问官方网站:https://www.dcloud.io/hbuilderx.html 根据您的操作系统选择合适版本: Windows版(推荐下载标准版) Windows系统安装步骤 运行安装程序: 双击下载的.exe安装文件 如果出现安全提示&…...
论文解读:交大港大上海AI Lab开源论文 | 宇树机器人多姿态起立控制强化学习框架(一)
宇树机器人多姿态起立控制强化学习框架论文解析 论文解读:交大&港大&上海AI Lab开源论文 | 宇树机器人多姿态起立控制强化学习框架(一) 论文解读:交大&港大&上海AI Lab开源论文 | 宇树机器人多姿态起立控制强化…...
QT: `long long` 类型转换为 `QString` 2025.6.5
在 Qt 中,将 long long 类型转换为 QString 可以通过以下两种常用方法实现: 方法 1:使用 QString::number() 直接调用 QString 的静态方法 number(),将数值转换为字符串: long long value 1234567890123456789LL; …...
dify打造数据可视化图表
一、概述 在日常工作和学习中,我们经常需要和数据打交道。无论是分析报告、项目展示,还是简单的数据洞察,一个清晰直观的图表,往往能胜过千言万语。 一款能让数据可视化变得超级简单的 MCP Server,由蚂蚁集团 AntV 团队…...
Linux 中如何提取压缩文件 ?
Linux 是一种流行的开源操作系统,它提供了许多工具来管理、压缩和解压缩文件。压缩文件有助于节省存储空间,使数据传输更快。本指南将向您展示如何在 Linux 中提取不同类型的压缩文件。 1. Unpacking ZIP Files ZIP 文件是非常常见的,要在 …...
【Linux】Linux 系统默认的目录及作用说明
博主介绍:✌全网粉丝23W,CSDN博客专家、Java领域优质创作者,掘金/华为云/阿里云/InfoQ等平台优质作者、专注于Java技术领域✌ 技术范围:SpringBoot、SpringCloud、Vue、SSM、HTML、Nodejs、Python、MySQL、PostgreSQL、大数据、物…...
