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

目录
- 一、 啥是建造者模式?
- 二、 为什么要用建造者模式?
- 三、 建造者模式怎么实现?
- 四、 建造者模式的应用场景
- 五、 建造者模式的优点和缺点
- 六、 总结
🌟我的其他文章也讲解的比较有趣😁,如果喜欢博主的讲解方式,可以多多支持一下,感谢🤗!
🌟了解原型模式请看: (四)趣学设计模式 之 原型模式!
这篇文章带你详细认识一下设计模式中的建造者模式
一、 啥是建造者模式?
建造者模式,就像组装乐高玩具 🧸! 你有一堆零件,想要拼出一个复杂的模型,比如一辆汽车 🚗 或者一栋房子 🏠,但是直接拼太麻烦了,容易出错,而且不同的汽车和房子,拼装步骤可能不一样。 建造者模式就是把组装过程分解成一步一步的,每一步负责一部分,比如安装引擎、安装轮胎、刷油漆等等,每一步都由专门的工人(具体建造者)来完成,最后把所有部分组合起来,就得到了完整的模型!
- 对象创建过程复杂: 就像盖房子 🏠,需要打地基、砌墙、安装门窗、装修等等,一步都不能少,而且顺序也很重要!
- 需要灵活控制对象创建过程: 就像定制汽车 🚗,可以根据自己的喜好选择不同的引擎、轮胎、颜色等等,每个配置都会影响最终的汽车!
- 希望隐藏对象内部的构建细节: 就像吃汉堡 🍔,你只想吃,不想知道它是怎么做的,更不想知道厨师是怎么一步一步把汉堡做出来的!
二、 为什么要用建造者模式?
用建造者模式,好处多多:
- 分工明确: 每个建造者负责一部分,职责清晰,代码更易维护! 就像盖房子,有专门的泥瓦匠砌墙,有专门的木匠安装门窗,每个人都只负责自己的部分,不会互相干扰!
- 灵活定制: 可以根据需要选择不同的建造者,创建不同配置的对象! 就像定制汽车,可以选择不同的引擎、轮胎、颜色等等,最终得到一辆完全符合自己需求的汽车!
- 隐藏细节: 客户端不用关心对象的构建过程,只需要知道最终的结果! 就像吃汉堡,你只需要知道汉堡很好吃,不用关心厨师是怎么一步一步把汉堡做出来的!
- 代码复用: 相同的构建步骤可以被不同的建造者复用! 就像盖房子,不同的房子可能都需要打地基,这个步骤就可以被不同的建造者复用!
三、 建造者模式怎么实现?
建造者模式主要包含以下几个角色:
- 产品(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 不能证明…...
React Native在HarmonyOS 5.0阅读类应用开发中的实践
一、技术选型背景 随着HarmonyOS 5.0对Web兼容层的增强,React Native作为跨平台框架可通过重新编译ArkTS组件实现85%以上的代码复用率。阅读类应用具有UI复杂度低、数据流清晰的特点。 二、核心实现方案 1. 环境配置 (1)使用React Native…...
Frozen-Flask :将 Flask 应用“冻结”为静态文件
Frozen-Flask 是一个用于将 Flask 应用“冻结”为静态文件的 Python 扩展。它的核心用途是:将一个 Flask Web 应用生成成纯静态 HTML 文件,从而可以部署到静态网站托管服务上,如 GitHub Pages、Netlify 或任何支持静态文件的网站服务器。 &am…...
数据链路层的主要功能是什么
数据链路层(OSI模型第2层)的核心功能是在相邻网络节点(如交换机、主机)间提供可靠的数据帧传输服务,主要职责包括: 🔑 核心功能详解: 帧封装与解封装 封装: 将网络层下发…...
sqlserver 根据指定字符 解析拼接字符串
DECLARE LotNo NVARCHAR(50)A,B,C DECLARE xml XML ( SELECT <x> REPLACE(LotNo, ,, </x><x>) </x> ) DECLARE ErrorCode NVARCHAR(50) -- 提取 XML 中的值 SELECT value x.value(., VARCHAR(MAX))…...
鸿蒙中用HarmonyOS SDK应用服务 HarmonyOS5开发一个生活电费的缴纳和查询小程序
一、项目初始化与配置 1. 创建项目 ohpm init harmony/utility-payment-app 2. 配置权限 // module.json5 {"requestPermissions": [{"name": "ohos.permission.INTERNET"},{"name": "ohos.permission.GET_NETWORK_INFO"…...
学校时钟系统,标准考场时钟系统,AI亮相2025高考,赛思时钟系统为教育公平筑起“精准防线”
2025年#高考 将在近日拉开帷幕,#AI 监考一度冲上热搜。当AI深度融入高考,#时间同步 不再是辅助功能,而是决定AI监考系统成败的“生命线”。 AI亮相2025高考,40种异常行为0.5秒精准识别 2025年高考即将拉开帷幕,江西、…...
html css js网页制作成品——HTML+CSS榴莲商城网页设计(4页)附源码
目录 一、👨🎓网站题目 二、✍️网站描述 三、📚网站介绍 四、🌐网站效果 五、🪓 代码实现 🧱HTML 六、🥇 如何让学习不再盲目 七、🎁更多干货 一、👨…...
LeetCode - 199. 二叉树的右视图
题目 199. 二叉树的右视图 - 力扣(LeetCode) 思路 右视图是指从树的右侧看,对于每一层,只能看到该层最右边的节点。实现思路是: 使用深度优先搜索(DFS)按照"根-右-左"的顺序遍历树记录每个节点的深度对于…...
C++:多态机制详解
目录 一. 多态的概念 1.静态多态(编译时多态) 二.动态多态的定义及实现 1.多态的构成条件 2.虚函数 3.虚函数的重写/覆盖 4.虚函数重写的一些其他问题 1).协变 2).析构函数的重写 5.override 和 final关键字 1&#…...
【MATLAB代码】基于最大相关熵准则(MCC)的三维鲁棒卡尔曼滤波算法(MCC-KF),附源代码|订阅专栏后可直接查看
文章所述的代码实现了基于最大相关熵准则(MCC)的三维鲁棒卡尔曼滤波算法(MCC-KF),针对传感器观测数据中存在的脉冲型异常噪声问题,通过非线性加权机制提升滤波器的抗干扰能力。代码通过对比传统KF与MCC-KF在含异常值场景下的表现,验证了后者在状态估计鲁棒性方面的显著优…...
