设计模式探索:建造者模式

ops/2024/9/19 12:19:00/ 标签: 设计模式, 建造者模式, java

1. 什么是建造者模式

建造者模式 (Builder Pattern),也被称为生成器模式,是一种创建型设计模式

  • 定义:将一个复杂对象的构建与表示分离,使得同样的构建过程可以创建不同的表示。

建造者模式要解决的问题:

  • 建造者模式可以将部件和其组装过程分开,一步一步创建一个复杂的对象。用户只需要指定复杂对象的类型就可以得到该对象,而无需知道其内部的具体构造细节。
    在这里插入图片描述

2. 建造者模式的结构

在这里插入图片描述

建造者(Builder)模式包含以下4个角色:

  1. 抽象建造者类(Builder):规定要实现复杂对象的哪些部分的创建,并不涉及具体的部件对象的创建。
  2. 具体建造者类(ConcreteBuilder):实现 Builder 接口,完成复杂产品的各个部件的具体创建方法。在构造过程完成后,提供一个方法,返回创建好的复杂产品对象。
  3. 产品类(Product):要创建的复杂对象 (包含多个组成部件)。
  4. 指挥者类(Director):调用具体建造者来创建复杂对象的各个部分,在指挥者中不涉及具体产品的信息,只负责保证对象各部分完整创建或按某种顺序创建(客户端一般只需要与指挥者进行交互)。

3. 代码示例

下面是一个SQL查询生成器的例子,展示如何使用建造者模式生成不同数据库的SQL查询语句。

产品类
java">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();}
}

抽象建造者

java">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();
}

具体建造者

java">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");}
}

指挥者类

java">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();}
}

客户端

java">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. 建造者模式在实际开发中的应用

建造者模式在实际开发中的应用主要体现在以下几个方面:

  1. 复杂对象的创建:例如,在创建一个复杂对象时,如果这个对象有很多可选参数,使用建造者模式可以避免构造函数参数列表过长的问题。
  2. 多步骤创建过程:例如,在构建SQL查询、创建报告等需要多个步骤的过程中,使用建造者模式可以将这些步骤分离出来,使得代码更易于维护和扩展。
  3. 对象的不变性:例如,创建一个不可变对象时,可以使用建造者模式来确保对象在创建后不被修改。

5. 建造者模式与工厂模式的区别

  1. 工厂模式

    • 用来创建不同但是相关类型的对象(继承同一父类或者接口的一组子类),由给定的参数来决定创建哪种类型的对象。
    • 主要关注的是创建单个对象。
      在这里插入图片描述
  2. 建造者模式

    • 用来创建一种类型的复杂对象,通过设置不同的可选参数,“定制化”地创建不同的对象。
    • 主要关注的是如何一步一步创建一个复杂的对象。
    • 更强调创建过程的分步和顺序。
      在这里插入图片描述

总之,建造者模式可以很好地解决创建复杂对象时的代码复用性和可维护性问题,而工厂模式则更加适用于创建一组相关的对象。


http://www.ppmy.cn/ops/56503.html

相关文章

pnpm workspace使用教程【Monorepo项目】

目录 前言一、pnpm简介特点&#xff1a;对比 二、 创建项目添加文件 pnpm-workspace.yaml目录结构pnpm workspace: 协议修改配置文件执行 安装 三、命令解析执行包命令所有包操作命令 四、实例代码 前言 前面两篇&#xff0c;我们讲了 yarn workspace 和 lerna &#xff0c; …

怎样在 PostgreSQL 中优化对大数值类型数据的计算?

文章目录 一、选择合适的数据类型二、索引优化三、查询语句优化四、数据库配置调整五、使用扩展功能六、示例七、总结 在 PostgreSQL 中处理大数值类型数据&#xff08;例如 BIGINT、NUMERIC 等&#xff09;的计算时&#xff0c;可能会遇到性能瓶颈。为了优化这些计算&#xff…

景点门票销售管理系统(数据库课设)

1.课设要求描述 ●实现票价管理&#xff0c;应分老年、小孩、成人、团体等&#xff1b; ●实现营业员管理&#xff1b; 实现门票销售、退票管理&#xff1b; ● 创建存储过程&#xff0c;统计指定日期的门票销售情况&#xff1b; ●创建存储过程&#xff0c;统计指定月份…

Idea 2023 使用GitLab提交代码提示输入Token

项目场景&#xff1a; 今天电脑换硬盘了&#xff0c;安装了 IDEA2023 款的社区版开发工具&#xff0c;下载代码后&#xff0c;提交并推送代码到远程服务器的时候&#xff0c;提示输入Token&#xff0c;并不是用户名和密码。 问题描述 推送代码到远程GitLab本地仓库的时候&…

AtCoder Beginner Contest 359

目录 A - A Healthy Breakfast B - Vertical Reading C - Move It D - Ghost Ants E - Random Swaps of Balls F.暂无 G - Suitable Edit for LIS A - A Healthy Breakfast 就三个字母直接模拟&#xff0c;只有xRM,RMx,RxM三种 void solve(){string a; cin>>a;i…

开源浏览器引擎对比与适用场景:WebKit、Chrome、Gecko

WebKit与Chrome的Blink引擎对比 起源与关系&#xff1a; WebKit最初由苹果公司开发&#xff0c;用于Safari浏览器。后来&#xff0c;WebKit逐渐成为一个独立的开源项目&#xff0c;被多个浏览器厂商采用。Blink是Google基于WebKit项目分支出来的一个浏览器引擎&#xff0c;用于…

回收家电哪个平台靠谱

在当今社会&#xff0c;随着科技的飞速发展和人们生活水平的不断提高&#xff0c;家电产品的更新换代速度越来越快。如何妥善处理日用家电&#xff0c;既能实现资源的有效利用&#xff0c;又能为环保出一份力&#xff0c;成为了许多人关注的焦点。在众多的家电回收平台中&#…

python-长方体边长和(赛氪OJ)

[题目描述] 给出共享长方体一个顶点的三个面的面积&#xff0c;求它十二条边的边长和。输入格式&#xff1a; 一行三个整数 a , b , c 表示面积。输出格式&#xff1a; 一行一个整数表示边长和。样例输入#1 1 1 1样例输出#1 12样例输入#2 4 6 6样例输出#2 28数据范围&#xff1…

在得物买珠宝的年轻人,是哪种level?

文 | 螳螂观察 作者 | 如意 卖潮鞋的社区电商得物&#xff0c;从改名之后开始扩品类&#xff0c;如今已经渐渐活成了缩略版的阿里、京东。 从饰品到食品&#xff0c;从3C到家居&#xff0c;超20个大众消费品类目都被得物囊括了。 目的很明显&#xff0c;做大做强、再创辉煌…

道可云元宇宙每日资讯|首批山东省数字产业集群拟认定名单发布

道可云元宇宙每日简报&#xff08;2024年7月11日&#xff09;讯&#xff0c;今日元宇宙新鲜事有&#xff1a; 首批山东省数字产业集群拟认定名单发布 7月9日&#xff0c;山东省工业和信息化厅发布关于拟认定首批山东省数字产业集群的公示。首批山东省数字产业集群拟认定名单共…

Vue实战【基于wangEditor富文本编辑器+拖拽实现一个自定义打印模版】

目录 &#x1f31f;前言&#x1f31f;需求&#x1f31f;效果预览&#x1f31f;安装wangEditor富文本编辑器&#x1f31f;拖拽API&#x1f31f;wangEditor富文本编辑器所用到的API&#x1f31f;写在最后&#x1f31f;JSON包里写函数&#xff0c;关注博主不迷路 &#x1f31f;前言…

前端面试题46(vue路由如何根据权限动态控制路由的显示?)

在 Vue 中&#xff0c;根据权限动态控制路由的显示通常涉及到两个主要步骤&#xff1a;权限检查和动态路由的添加。下面是一个概括性的流程&#xff0c;以及如何具体实现这一功能的示例代码。 第一步&#xff1a;定义权限和角色 首先&#xff0c;你需要定义好不同的角色和它们…

迅为RK3562核心板四核A53+MaliG52架构,应用于商业平板电脑,视频会议,智能家居,教育电子,医疗设备,边缘计算,工业应用

迅为RK3562核心板四核A53MaliG52架构,应用于商业平板电脑,视频会议,智能家居,教育电子,医疗设备,边缘计算,工业应用

微软Edge浏览器全解析:从速度到安全性的全面体验

微软Edge浏览器&#xff0c;自2015年首次亮相以来&#xff0c;已经成为了浏览器市场上不可忽视的一股力量。它不仅集成了Windows 10的许多原生功能&#xff0c;还在速度和安全性上进行了大量的优化。本文将全面解析微软Edge浏览器的各项特性&#xff0c;带您领略这款浏览器的魅…

视频版权音乐处理☞AI分离人声、音效、背景音乐的需求和进展-2024

随着互联网的普及和短视频的兴起&#xff0c;视频内容的全球各大平台分发越来越普遍。然而&#xff0c;不同国家和地区的音乐版权、不同社媒平台拥有的版权和处理政策都存在差异&#xff0c;因此同一个视频在多渠道分发的时候就会产生版权侵权风险。如何既能满足全球多渠道、多…

【排序算法】归并排序

一.基本思想 归并排序是采用分治法的一个非常典型的应用。它将已经有序的序列合并为完全有序的序列&#xff0c;即先使得每一个子序列有序&#xff0c;再让子序列之间有序。归并排序建立在归并操作上&#xff0c;以下动图能很好的演示归并排序中归并的过程&#xff1a; 但上图…

小程序-自定义导航栏

小程序默认的导航栏与APP 一样都位于顶部固定位置。但是默认导航栏可能会影响小程序整体风格&#xff0c;且无法满足特定的设计需求&#xff0c;这时候&#xff0c;就需要自定义导航栏。 在 app.json 或者 page.json 中&#xff0c;配置 navigationStyle 属性为 custom &#x…

Chrome 127内置AI大模型攻略

Chrome 127 集成Gemini:本地AI功能 Google将Gemini大模型整合进Chrome浏览器,带来全新免费的本地AI体验: 完全免费、无限制使用支持离线运行,摆脱网络依赖功能涵盖图像识别、自然语言处理、智能推荐等中国大陆需要借助魔法,懂都懂。 安装部署步骤: 1. Chrome V127 dev …

码云远程仓库, 回滚到指定版本号

1. 打开项目路径, 右击Git Bash Here 2. 查找历史版本 git reflog 3. 回退到指定版本 git reset --hard 版本号 4. 强制推送到远程 git push -f

生产英特尔CPU处理器繁忙的一天

早晨&#xff1a;准备与检查 7:00 AM - 起床与准备 工厂员工们早早起床&#xff0c;快速洗漱并享用早餐。为了在一天的工作中保持高效&#xff0c;他们会进行一些晨间锻炼&#xff0c;保持头脑清醒和身体活力。 8:00 AM - 到达工厂 员工们到达英特尔的半导体制造工厂&#…