设计模式探索:建造者模式
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 对象只包含整数值元素,并且元素数量不大时,就会使用整数集合这个数据结构作为底层实现。整数集合通过紧凑的内存布局和升级机制,实现了…...
深入浅出Asp.Net Core MVC应用开发系列-AspNetCore中的日志记录
ASP.NET Core 是一个跨平台的开源框架,用于在 Windows、macOS 或 Linux 上生成基于云的新式 Web 应用。 ASP.NET Core 中的日志记录 .NET 通过 ILogger API 支持高性能结构化日志记录,以帮助监视应用程序行为和诊断问题。 可以通过配置不同的记录提供程…...
椭圆曲线密码学(ECC)
一、ECC算法概述 椭圆曲线密码学(Elliptic Curve Cryptography)是基于椭圆曲线数学理论的公钥密码系统,由Neal Koblitz和Victor Miller在1985年独立提出。相比RSA,ECC在相同安全强度下密钥更短(256位ECC ≈ 3072位RSA…...
.Net框架,除了EF还有很多很多......
文章目录 1. 引言2. Dapper2.1 概述与设计原理2.2 核心功能与代码示例基本查询多映射查询存储过程调用 2.3 性能优化原理2.4 适用场景 3. NHibernate3.1 概述与架构设计3.2 映射配置示例Fluent映射XML映射 3.3 查询示例HQL查询Criteria APILINQ提供程序 3.4 高级特性3.5 适用场…...
ESP32读取DHT11温湿度数据
芯片:ESP32 环境:Arduino 一、安装DHT11传感器库 红框的库,别安装错了 二、代码 注意,DATA口要连接在D15上 #include "DHT.h" // 包含DHT库#define DHTPIN 15 // 定义DHT11数据引脚连接到ESP32的GPIO15 #define D…...
Java - Mysql数据类型对应
Mysql数据类型java数据类型备注整型INT/INTEGERint / java.lang.Integer–BIGINTlong/java.lang.Long–––浮点型FLOATfloat/java.lang.FloatDOUBLEdouble/java.lang.Double–DECIMAL/NUMERICjava.math.BigDecimal字符串型CHARjava.lang.String固定长度字符串VARCHARjava.lang…...
什么是EULA和DPA
文章目录 EULA(End User License Agreement)DPA(Data Protection Agreement)一、定义与背景二、核心内容三、法律效力与责任四、实际应用与意义 EULA(End User License Agreement) 定义: EULA即…...
C++中string流知识详解和示例
一、概览与类体系 C 提供三种基于内存字符串的流,定义在 <sstream> 中: std::istringstream:输入流,从已有字符串中读取并解析。std::ostringstream:输出流,向内部缓冲区写入内容,最终取…...
SpringCloudGateway 自定义局部过滤器
场景: 将所有请求转化为同一路径请求(方便穿网配置)在请求头内标识原来路径,然后在将请求分发给不同服务 AllToOneGatewayFilterFactory import lombok.Getter; import lombok.Setter; import lombok.extern.slf4j.Slf4j; impor…...
高防服务器能够抵御哪些网络攻击呢?
高防服务器作为一种有着高度防御能力的服务器,可以帮助网站应对分布式拒绝服务攻击,有效识别和清理一些恶意的网络流量,为用户提供安全且稳定的网络环境,那么,高防服务器一般都可以抵御哪些网络攻击呢?下面…...
均衡后的SNRSINR
本文主要摘自参考文献中的前两篇,相关文献中经常会出现MIMO检测后的SINR不过一直没有找到相关数学推到过程,其中文献[1]中给出了相关原理在此仅做记录。 1. 系统模型 复信道模型 n t n_t nt 根发送天线, n r n_r nr 根接收天线的 MIMO 系…...
