设计模式探索:建造者模式
1. 什么是建造者模式
建造者模式 (Builder Pattern),也被称为生成器模式,是一种创建型设计模式。
- 定义:将一个复杂对象的构建与表示分离,使得同样的构建过程可以创建不同的表示。
建造者模式要解决的问题:
- 建造者模式可以将部件和其组装过程分开,一步一步创建一个复杂的对象。用户只需要指定复杂对象的类型就可以得到该对象,而无需知道其内部的具体构造细节。

2. 建造者模式的结构

建造者(Builder)模式包含以下4个角色:
- 抽象建造者类(Builder):规定要实现复杂对象的哪些部分的创建,并不涉及具体的部件对象的创建。
- 具体建造者类(ConcreteBuilder):实现 Builder 接口,完成复杂产品的各个部件的具体创建方法。在构造过程完成后,提供一个方法,返回创建好的复杂产品对象。
- 产品类(Product):要创建的复杂对象 (包含多个组成部件)。
- 指挥者类(Director):调用具体建造者来创建复杂对象的各个部分,在指挥者中不涉及具体产品的信息,只负责保证对象各部分完整创建或按某种顺序创建(客户端一般只需要与指挥者进行交互)。
3. 代码示例
下面是一个SQL查询生成器的例子,展示如何使用建造者模式生成不同数据库的SQL查询语句。
产品类
public class SqlQuery {private String select;private String from;private String where;private String groupBy;private String orderBy;private String limit;public SqlQuery(String select, String from) {this.select = select;this.from = from;}// Getters and setters@Overridepublic String toString() {StringBuilder sb = new StringBuilder();sb.append("SELECT ").append(select).append(" FROM ").append(from);if (where != null && !where.isEmpty()) {sb.append(" WHERE ").append(where);}if (groupBy != null && !groupBy.isEmpty()) {sb.append(" GROUP BY ").append(groupBy);}if (orderBy != null && !orderBy.isEmpty()) {sb.append(" ORDER BY ").append(orderBy);}if (limit != null && !limit.isEmpty()) {sb.append(" LIMIT ").append(limit);}return sb.toString();}
}
抽象建造者
public abstract class SqlQueryBuilder {protected SqlQuery sqlQuery;public void createSqlQuery(String select, String from) {sqlQuery = new SqlQuery(select, from);}public SqlQuery getSqlQuery() {return sqlQuery;}public abstract void buildWhere();public abstract void buildGroupBy();public abstract void buildOrderBy();public abstract void buildLimit();
}
具体建造者
public class MySqlQueryBuilder extends SqlQueryBuilder {@Overridepublic void buildWhere() {sqlQuery.setWhere("1 = 1"); // MySQL不需要限制行数}@Overridepublic void buildGroupBy() {sqlQuery.setGroupBy("deptno, ename, hiredate");}@Overridepublic void buildOrderBy() {sqlQuery.setOrderBy("hiredate DESC");}@Overridepublic void buildLimit() {sqlQuery.setLimit("0, 10"); // MySQL分页从0开始}
}public class OracleQueryBuilder extends SqlQueryBuilder {@Overridepublic void buildWhere() {sqlQuery.setWhere("rownum <= 1000"); // Oracle查询最多返回1000行数据}@Overridepublic void buildGroupBy() {sqlQuery.setGroupBy("deptno, ename, hiredate");sqlQuery.setSelect(sqlQuery.getSelect() + ", deptno, ename, hiredate");}@Overridepublic void buildOrderBy() {sqlQuery.setOrderBy("hiredate");}@Overridepublic void buildLimit() {sqlQuery.setLimit("10");}
}
指挥者类
public class SqlQueryDirector {private SqlQueryBuilder sqlQueryBuilder;public void setSqlQueryBuilder(SqlQueryBuilder sqlQueryBuilder) {this.sqlQueryBuilder = sqlQueryBuilder;}public void buildSqlQuery(String select, String from) {sqlQueryBuilder.createSqlQuery(select, from);sqlQueryBuilder.buildWhere();sqlQueryBuilder.buildGroupBy();sqlQueryBuilder.buildOrderBy();sqlQueryBuilder.buildLimit();}
}
客户端
public class Client {public static void main(String[] args) {// 创建MySQL建造者SqlQueryBuilder mySqlQueryBuilder = new MySqlQueryBuilder();// 创建Oracle建造者SqlQueryBuilder oracleQueryBuilder = new OracleQueryBuilder();// 指导者SqlQueryDirector sqlQueryDirector = new SqlQueryDirector();// 构建MySQL查询语句sqlQueryDirector.setSqlQueryBuilder(mySqlQueryBuilder);sqlQueryDirector.buildSqlQuery("*", "table1");SqlQuery mySqlQuery = mySqlQueryBuilder.getSqlQuery();System.out.println("MySQL Query: " + mySqlQuery);// 构建Oracle查询语句sqlQueryDirector.setSqlQueryBuilder(oracleQueryBuilder);sqlQueryDirector.buildSqlQuery("*", "table2");SqlQuery oracleQuery = oracleQueryBuilder.getSqlQuery();System.out.println("Oracle Query: " + oracleQuery);}
}
4. 建造者模式在实际开发中的应用
建造者模式在实际开发中的应用主要体现在以下几个方面:
- 复杂对象的创建:例如,在创建一个复杂对象时,如果这个对象有很多可选参数,使用建造者模式可以避免构造函数参数列表过长的问题。
- 多步骤创建过程:例如,在构建SQL查询、创建报告等需要多个步骤的过程中,使用建造者模式可以将这些步骤分离出来,使得代码更易于维护和扩展。
- 对象的不变性:例如,创建一个不可变对象时,可以使用建造者模式来确保对象在创建后不被修改。
5. 建造者模式与工厂模式的区别
-
工厂模式:
- 用来创建不同但是相关类型的对象(继承同一父类或者接口的一组子类),由给定的参数来决定创建哪种类型的对象。
- 主要关注的是创建单个对象。

-
建造者模式:
- 用来创建一种类型的复杂对象,通过设置不同的可选参数,“定制化”地创建不同的对象。
- 主要关注的是如何一步一步创建一个复杂的对象。
- 更强调创建过程的分步和顺序。

总之,建造者模式可以很好地解决创建复杂对象时的代码复用性和可维护性问题,而工厂模式则更加适用于创建一组相关的对象。
相关文章:
设计模式探索:建造者模式
1. 什么是建造者模式 建造者模式 (Builder Pattern),也被称为生成器模式,是一种创建型设计模式。 定义:将一个复杂对象的构建与表示分离,使得同样的构建过程可以创建不同的表示。 建造者模式要解决的问题: 建造者模…...
[Go] 字符串遍历数据类型问题
字符串遍历问题 在使用for i,v:range str遍历字符串时 str[i]是unit8(byte)类型,返回的是单个字节 字符串在Go中是以字节序列的形式存储的,而 str[i] 直接访问了这个字节序列中的第 i 个字节。如果字符串中的字符是单字节的ASCII…...
HJ41 称砝码
HJ41 称砝码 提示:文章 文章目录 前言一、背景二、 2.1 2.2 总结 前言 前期疑问: 本文目标: 一、背景 这个题目之前是没有做出来的,我把之前没做出来的代码也记录一下 二、 2.1 之前的代码 #include <stdio.h>int m…...
如何使用Python脚本实现SSH登录
调试IDE:PyCharm Python库:Paramiko 首先安装Paramiko包到PyCharm,具体步骤为:在打开的PyCharm工具中,选择顶部菜单栏中“File”下的“Settings”,在设置对话框中,选择“Project”下的“Proje…...
2024年文化研究与数字媒体国际会议 (CRDM 2024)
2024年文化研究与数字媒体国际会议 (CRDM 2024) 2024 International Conference on Cultural Research and Digital Media 【重要信息】 大会地点:珠海 大会官网:http://www.iccrdm.com 投稿邮箱:iccrdmsub-conf.com 【注意:稿将…...
14-52 剑和诗人26 - RAG 和 VectorDB 简介
检索增强生成 (RAG) 和 VectorDB 是自然语言处理 (NLP) 中的两个重要概念,它们正在突破 AI 系统所能实现的界限。 在这篇博文中,我将深入探讨 RAG,探索其工作原理、应用、优势和局限性。 我们还将研究 VectorDB,这是一种专用于向…...
如果MySQL出现 “Too many connections“ 错误,该如何解决?
当你想要连接MySQL时出现"Too many connections" 报错的情况下,该如何解决才能如愿以偿呢?都是哥们儿,就教你两招吧! 1.不想重启数据库的情况下 你可以尝试采取以下方法来解决: 增加连接数限制:…...
论文阅读:Rethinking Interpretability in the Era of Large Language Models
Rethinking Interpretability in the Era of Large Language Models 《Rethinking Interpretability in the Era of Large Language Models》由Chandan Singh、Jeevana Priya Inala、Michel Galley、Rich Caruana和Jianfeng Gao撰写,探讨了在大型语言模型ÿ…...
C++/Qt 信号槽机制详解
文章目录 C++/Qt 信号槽机制详解一、信号和槽的基本概念1. 信号2. 槽3. 连接二、信号和槽的基本使用1. 信号和槽的声明和定义2. 连接信号和槽三、信号和槽的工作原理1. MOC(Meta-Object Compiler)2. 事件循环3. 连接类型四、信号和槽的高级应用1. 自定义信号和槽2. Lambda 表…...
duplicate key value violates unique constraint
duplicate key value violates unique constraint 遇到的问题 你在尝试向数据库表 goods 插入新记录时,收到了 duplicate key value violates unique constraint 的错误。尽管你确认数据库中没有与尝试插入的 id 相同的记录,但错误依旧存在。进一步的调…...
YOLOv10改进 | EIoU、SIoU、WIoU、DIoU、FocusIoU等二十余种损失函数
一、本文介绍 这篇文章介绍了YOLOv10的重大改进,特别是在损失函数方面的创新。它不仅包括了多种IoU损失函数的改进和变体,如SIoU、WIoU、GIoU、DIoU、EIOU、CIoU,还融合了“Focus”思想,创造了一系列新的损失函数。这些组合形式的…...
docker nginx mysql redis
启动没有数据卷的nginx docker run -d -p 86:80 --name my-nginx nginx把/etc/nginx中的配置复制到宿主机 docker cp my-nginx:/etc/nginx /home/nginxlkl把/html 中的文件复制到宿主机 docker cp my-nginx:/etc/nginx /home/nginxlkl删除当前镜像 docker rm -f my-nginx重新起…...
Linux系统(CentOS)安装iptables防火墙
1,先检查是否安装了iptables 检查安装文件-执行命令:rpm -qa|grep iptables 检查安装文件-执行命令:service iptables status 2,如果安装了就卸装(iptables-1.4.21-35.el7.x86_64 是上面命令查出来的版本) 执行命令:…...
华为的服务器创新之路
华为作为全球领先的信息与通信技术解决方案供应商,其在服务器领域的创新方法不仅推动了企业自身的发展,也为整个行业的进步做出了重要贡献。以下是华为在服务器领域所采取的一些关键创新方法: 芯片级的自主创新 华为通过自主研发的“鲲鹏”处…...
对比service now和salesforce
目录 1. 核心功能和用途 2. 市场定位 3. 平台和扩展性 4. 用户界面和用户体验 5. 价格 总结 ServiceNow和Salesforce是两款广泛使用的企业软件平台,但它们的侧重点和用途有所不同。以下是对它们的详细比较: 1. 核心功能和用途 ServiceNow IT服务…...
树状数组
树状数组 树状数组的核心思想:分治。将数组以二叉树的形式进行维护区间之和。 设 a a a为原数组, t r e e tree tree为树状数组。 t r e e tree tree数组用于存储树上该结点下严格直连的子节点之和(例: t [ 1 ] a [ 1 ] , t [ 2 ] t [ 1 …...
【北京迅为】《i.MX8MM嵌入式Linux开发指南》-第一篇 嵌入式Linux入门篇-
i.MX8MM处理器采用了先进的14LPCFinFET工艺,提供更快的速度和更高的电源效率;四核Cortex-A53,单核Cortex-M4,多达五个内核 ,主频高达1.8GHz,2G DDR4内存、8G EMMC存储。千兆工业级以太网、MIPI-DSI、USB HOST、WIFI/BT…...
ansible常见问题配置好了密码还是报错
| FAILED! > { “msg”: “Using a SSH password instead of a key is not possible because Host Key checking is enabled and sshpass does not support this. Please add this host’s fingerprint to your known_hosts file to manage this host.” } 怎么解决…...
python-课程满意度计算(赛氪OJ)
[题目描述] 某个班主任对学生们学习的的课程做了一个满意度调查,一共在班级内抽取了 N 个同学,对本学期的 M 种课程进行满意度调查。他想知道,有多少门课是被所有调查到的同学都喜欢的。输入格式: 第一行输入两个整数 N , M 。 接…...
6、Redis系统-数据结构-05-整数
五、整数集合(Intset) 整数集合是 Redis 中 Set 对象的底层实现之一。当一个 Set 对象只包含整数值元素,并且元素数量不大时,就会使用整数集合这个数据结构作为底层实现。整数集合通过紧凑的内存布局和升级机制,实现了…...
3步搞定开源工具ESLyric歌词源配置指南
3步搞定开源工具ESLyric歌词源配置指南 【免费下载链接】ESLyric-LyricsSource Advanced lyrics source for ESLyric in foobar2000 项目地址: https://gitcode.com/gh_mirrors/es/ESLyric-LyricsSource 在数字音乐播放体验中,歌词显示的精准度与丰富度直接影…...
Chatterbox:多语言语音合成的开源解决方案
Chatterbox:多语言语音合成的开源解决方案 【免费下载链接】chatterbox Open source TTS model 项目地址: https://gitcode.com/GitHub_Trending/chatterbox7/chatterbox Chatterbox是一款由Resemble AI开发的开源语音合成(TTS)模型&a…...
别再纠结选哪个了!CAN、串口、蓝牙、TCP,手把手教你根据项目场景选通信协议(附Android实战代码)
通信协议选型实战指南:从车载系统到智能家居的黄金法则 当你在凌晨三点的办公室里盯着四块显示器,面前摆着CAN分析仪、蓝牙嗅探器和串口调试终端时,突然意识到项目deadline就在明天——这种场景对嵌入式开发者来说再熟悉不过了。选择错误的通…...
5个WebGL流体模拟创新体验让你轻松打造动态视觉艺术
5个WebGL流体模拟创新体验让你轻松打造动态视觉艺术 【免费下载链接】WebGL-Fluid-Simulation Play with fluids in your browser (works even on mobile) 项目地址: https://gitcode.com/gh_mirrors/web/WebGL-Fluid-Simulation 当静态网页设计已无法满足用户对交互体验…...
如何创建自定义编程连字符号:Hasklig字体开发终极指南
如何创建自定义编程连字符号:Hasklig字体开发终极指南 【免费下载链接】Hasklig Hasklig - a code font with monospaced ligatures 项目地址: https://gitcode.com/gh_mirrors/ha/Hasklig Hasklig是一款专为程序员设计的等宽字体,它通过创新的连…...
从ChatGPT插件到MCP:一个AI开发者亲历的工具集成进化史
从ChatGPT插件到MCP:一个AI开发者亲历的工具集成进化史 三年前,当我第一次尝试让ChatGPT调用外部API时,需要手动拼接JSON参数、处理OAuth认证、设计错误重试机制——光是让模型能查询天气就耗费了两天时间。如今,通过MCP协议&…...
React Native WebRTC M124版本终极指南:未来发展方向与特性深度解析
React Native WebRTC M124版本终极指南:未来发展方向与特性深度解析 【免费下载链接】react-native-webrtc The WebRTC module for React Native 项目地址: https://gitcode.com/gh_mirrors/re/react-native-webrtc React Native WebRTC是React Native生态中…...
保姆级教程:用YOLOv8+PyQt5打造你的番茄成熟度检测桌面应用(附完整源码与数据集)
从零构建番茄成熟度检测桌面应用:YOLOv8与PyQt5深度整合实战 在农业智能化浪潮中,计算机视觉技术正逐步改变传统农业生产方式。以番茄种植为例,成熟度判断直接影响采摘效率和经济效益。本文将带您完整实现一个结合YOLOv8目标检测与PyQt5图形界…...
如何快速部署AI模型:免费本地化解决方案完整指南
如何快速部署AI模型:免费本地化解决方案完整指南 【免费下载链接】LocalAI mudler/LocalAI: LocalAI 是一个开源项目,旨在本地运行机器学习模型,减少对云服务的依赖,提高隐私保护。 项目地址: https://gitcode.com/GitHub_Trend…...
破解微信小程序video组件的限制:3种禁止拖动进度条的实战方案对比
微信小程序视频播放控制深度解析:3种禁止拖动进度条的工程化方案 在知识付费和在线教育类小程序中,视频内容的完整播放率直接影响知识传递效果。但微信小程序原生video组件的enable-progress-gesture属性仅能禁用触摸手势,无法真正阻止进度条…...
