当前位置: 首页 > news >正文

java设计模式-生成器模式

文章目录

  • 生成器模式(Builder)
    • 1、目的和适用场景
    • 2、角色和职责
    • 3、实现步骤
    • 4、示例1
    • 5、示例2
    • 6、优点
    • 7、示例场景

生成器模式(Builder)

生成器模式(Builder Pattern)是一种创建型设计模式,它用于构造一个复杂对象的步骤分离。这样可以使用相同的构建过程创建不同的表示。生成器模式通常用于解决当一个对象需要多个部分来一步步构建时,直接实例化对象会导致构造方法过于复杂,参数列表过长的问题。使用生成器模式可以使对象的构建过程和表示分离,允许用户只通过指定复杂对象的类型和内容就可以构建它们,隐藏了对象的内部结构和构建过程。

1、目的和适用场景

生成器模式的主要目的是将一个复杂对象的构建与其表示分离,使得同样的构建过程可以创建不同的表示。这种模式特别适用于以下场景:

  • 当创建复杂对象的算法应该独立于该对象的组成部分以及它们的装配方式时。
  • 当构造过程必须允许被构造的对象有不同的表示时。

2、角色和职责

  1. 产品(Product):最终要创建的对象,通常包含多个组成部分。
  2. 生成器(Builder):定义创建产品对象所需的所有操作的接口或抽象类。
  3. 具体生成器(Concrete Builder):实现Builder接口的类,提供构建产品的具体实现。它负责创建产品对象的各个部分,并记录产品各部分的构造过程。
  4. 指导者(Director):负责安排已有模块的构造步骤,不涉及具体产品信息,只负责保证对象各部分完整创建或按某种顺序创建。
  5. 客户端(Client):使用生成器模式的地方,它将指导者和具体生成器关联起来,以创建复杂对象。

3、实现步骤

  1. 定义产品类:创建一个包含多个组成部件的复杂对象。
  2. 定义生成器接口:声明在所有类型生成器中通用的产品构造步骤。
  3. 实现具体生成器:为创建一个特定的产品变体提供实现。
  4. 定义指导者类:定义调用构建步骤的顺序来创建产品的方法。
  5. 客户端代码:创建一个生成器对象,将其传递给指导者,然后初始化构造过程。最后,从生成器对象中获取最终结果。

4、示例1

考虑一个简单的例子,我们需要创建一个文档对象,它可能包括标题、正文、图像等部分。我们可以使用生成器模式来灵活构造各种文档。

// 产品类
public class Document {private String title;private String body;private List<String> images = new ArrayList<>();public void setTitle(String title) {this.title = title;}public void setBody(String body) {this.body = body;}public void addImage(String image) {images.add(image);}public void showDocument() {System.out.println("Document Title: " + title);System.out.println("Body: " + body);System.out.println("Images: " + String.join(", ", images));}
}// 抽象生成器
public interface DocumentBuilder {void buildTitle(String title);void buildBody(String body);void buildImage(String image);Document getDocument();
}// 具体生成器
public class ConcreteDocumentBuilder implements DocumentBuilder {private Document document = new Document();@Overridepublic void buildTitle(String title) {document.setTitle(title);}@Overridepublic void buildBody(String body) {document.setBody(body);}@Overridepublic void buildImage(String image) {document.addImage(image);}@Overridepublic Document getDocument() {return document;}
}// 指导者
public class Director {private DocumentBuilder builder;public Director(DocumentBuilder builder) {this.builder = builder;}public void construct(String title, String body, List<String> images) {builder.buildTitle(title);builder.buildBody(body);for (String image : images) {builder.buildImage(image);}}
}// 客户端
public class Client {public static void main(String[] args) {DocumentBuilder builder = new ConcreteDocumentBuilder();Director director = new Director(builder);List<String> images = Arrays.asList("Image1", "Image2");director.construct("My Title", "This is the body.", images);Document document = builder.getDocument();document.showDocument();}
}

在这个例子中,ConcreteDocumentBuilder类实现了DocumentBuilder接口,提供了构建Document对象各个部分的

5、示例2

假设我们需要构建一个复杂的Car对象,它包含engine, seats, GPS等多个部分。

// 产品类
public class Car {private String engine;private int seats;private boolean GPS;// Car的构造器/Setter略去,提供设置各个属性的方法
}// 生成器接口
public interface Builder {void setEngine(String engine);void setSeats(int seats);void setGPS(boolean GPS);
}// 具体生成器
public class CarBuilder implements Builder {private Car car;public CarBuilder() {this.car = new Car();}@Overridepublic void setEngine(String engine) {car.setEngine(engine);}@Overridepublic void setSeats(int seats) {car.setSeats(seats);}@Overridepublic void setGPS(boolean GPS) {car.setGPS(GPS);}public Car build() {return car;}
}// 指导者
public class Director {public void constructSportsCar(Builder builder) {builder.setEngine("Sport Engine");builder.setSeats(2);builder.setGPS(true);}// 可以定义更多constructXxxCar方法以构建不同类型的汽车
}// 客户端代码
public class Demo {public static void main(String[] args) {CarBuilder builder = new CarBuilder();Director director = new Director();// 指导者使用具体生成器实例进行构建操作director.constructSportsCar(builder);// 从生成器中获取最终构建的产品Car car = builder.build();System.out.println(car);}
}

6、优点

  • 封装性好:客户端不需要知道产品内部组成的细节。
  • 构建和表示分离:构建算法可以独立于产品的组成部分以及它们的装配方式。
  • 更好的复用性:由于构建过程被封装在指导

生成器(Builder)模式的使用场景主要集中在需要构建一个复杂对象时,特别是当这个对象的构造过程需要多个步骤,或者构造参数很多,而且许多参数具有默认值。具体的应用场景包括:

  1. 分离复杂对象的构造和表示
    当创建复杂对象的过程一致,但对象的内部表示可能变化时,生成器模式提供了非常灵活的解决方案。通过相同的构建过程可以创建不同的表示。
  2. 控制复杂对象的构造过程
    生成器模式将一个复杂对象的构造过程封装在其对应的生成器中,使得这个构造过程被局部化,且可以被重复使用。这样做还能使构造代码与表示代码分离,降低系统的耦合度。
  3. 参数过多的对象创建
    对于一个参数数量很多的对象,尤其是大多数参数都有默认值时,使用传统的构造函数会非常繁琐。生成器模式允许客户端仅通过必需的参数构造对象,并通过链式调用方式设置其他可选参数。
  4. 需要构建的对象应具有不同的变体,而不是重载大量构造函数
    当一个类需要大量的构造函数,参数组合较多时,使用生成器模式可以避免构造函数过多,使得构造过程更清晰。
  5. 创建复合对象
    复合对象是指那些包含其他对象的对象。对于这样的对象,使用生成器模式可以先创建其包含的对象,然后再按照一定的步骤和顺序构造复合对象。

7、示例场景

  • 文本转换器:将一个文档转换成多种格式,例如HTML、纯文本或者RTF格式。每种转换器都可以作为一个具体的生成器,而文档的读取过程则是统一的。
  • 用户界面构建器:在GUI应用程序中,可能需要创建复杂的用户界面。生成器模式可以逐步构建用户界面的各个部分,如菜单、工具栏、按钮等,最后组合成完整的用户界面。
  • SQL查询构造器:用于构建复杂的SQL查询,允许动态添加不同的条件、选择字段、设置排序规则等,最后生成完整的SQL语句。
    生成器模式通过将对象的构造过程从其表示中分离,使得相同的构建过程可以创建不同的表示,为复杂对象的创建提供了更高的灵活性和控制力。

相关文章:

java设计模式-生成器模式

文章目录 生成器模式&#xff08;Builder&#xff09;1、目的和适用场景2、角色和职责3、实现步骤4、示例15、示例26、优点7、示例场景 生成器模式&#xff08;Builder&#xff09; 生成器模式&#xff08;Builder Pattern&#xff09;是一种创建型设计模式&#xff0c;它用于…...

《前端面试题》- TypeScript - TypeScript的优/缺点

问题 简述TypeScript的优/缺点 答案 优点 增强了代码的可读性和可维护性包容性&#xff0c;js可以直接改成ts&#xff0c;ts编译报错也可以生成js文件&#xff0c;兼容第三方库&#xff0c;即使不是ts编写的社区活跃&#xff0c;完全支持es6 缺点 增加学习成本增加开发成…...

微服务---feign调用服务

目录 Feign简介 Feign的作用 Feign的使用步骤 引入依赖 具体业务逻辑 配置日志 在其它服务中使用接口 接着上一篇博客&#xff0c;我们讲过了nacos的基础使用&#xff0c;知道它是注册服务用的&#xff0c;接下来我们我们思考如果一个服务需要调用另一个服务的接口信息&…...

刷题笔记 - 滑动窗口

文章目录 滑动窗口最长无重复子串最小覆盖子串串联所有单词的子串长度最小的子数组滑动窗口最大值字符串的排列最小区间 滑动窗口 所有题目来自leetcode的回答&#xff1a;https://leetcode.cn/problems/longest-substring-without-repeating-characters/solutions/3982/hua-d…...

Docker搭建LNMP+Wordpress的实验

目录 一、项目的介绍 1、项目需求 2、服务器环境 3、任务需求 二、Linux系统基础镜像 三、部署Nginx 1、建立工作目录 2、编写Dockerfile 3、准备nginx.conf配置文件 4、设置自定义网段和创建镜像和容器 5、启动镜像容器 6、验证nginx 三、Mysql 1、建立工作目录…...

使用Python Pandas实现两表对应列相加(即使表头不同)

目录 引言 Pandas库简介 实现对应列相加 步骤一&#xff1a;加载数据 步骤二&#xff1a;重命名列 步骤三&#xff1a;对应列相加 步骤四&#xff1a;保存结果 案例分析 结论 引言 在数据分析和处理的日常工作中&#xff0c;我们经常会遇到需要将来自不同数据源的数据…...

Linux 虚拟主机切换php版本及参数

我使用的Hostease的Linux虚拟主机产品,由于网站程序需要支持高版本的PHP,程序已经上传到主机&#xff0c;但是没有找到切换PHP以及查看PHP有哪些版本的位置&#xff0c;因此咨询了Hostease的技术支持&#xff0c;寻求帮助了解到可以实现在cPanel面板上找到此切换PHP版本的按钮&…...

Content-Type详解

...

GaussDB数据库SQL系列-复合查询

目录 一、前言 二、复合查询基础 三、实际应用示例 1、使用UNION合并查询结果 2、使用INTERSECT找出共同元素 3、使用EXCEPT排除特定结果 四、高级技巧 1、子查询实例 2、JOIN的应用 五、总结 一、前言 GaussDB是华为自主创新研发的分布式关系型数据库&#xff0c;具…...

【Unity】修改模型透明度

在 Unity 中修改模型透明度主要有两种方法&#xff1a;通过材质和通过着色器。以下是两种方法的步骤和解释&#xff1a; 方法 1&#xff1a;通过材质 在 Unity 编辑器中&#xff0c;选择你想要修改透明度的模型。在 Inspector 窗口中&#xff0c;找到模型的 Renderer 组件&am…...

第五篇:通信脉络:探索计算机外设与总线体系的精髓

通信脉络&#xff1a;探索计算机外设与总线体系的精髓 1 引言 在这个技术日新月异的时代&#xff0c;理解计算机系统的基本构成要素 —— 总线和外设 —— 对于每个从事技术工作的人来说都是至关重要的。这些组件不仅是计算机通信的基石&#xff0c;也直接影响着系统的性能、效…...

24.5.5(离散化+树状数组,线段树)

星期一&#xff1a; dp题单 背包 第四题 混可乐 cf传送门 思路&#xff1a;条件可演化为每种可乐值为 ai-n&#xff0c;选最少的可乐使总和为0&#xff08;具体可看官方题解 到这会发现背包并不适合了&#xff0c;其实这是道bfs伪装的背包…...

C语言 | Leetcode C语言题解之第69题x的平方根

题目&#xff1a; 题解&#xff1a; int mySqrt(int x) {long int i 0;for(i0;;i){long int a i*i;long int b (i1)*(i1);if(a < x&&b > x){break;}}return i; }...

静态分配IP,解决本地连接不上Linux虚拟机的问题

在Window环境下&#xff0c;使用远程终端工具连接不了VMware搭建的Linux虚拟机&#xff08;CentOS 7&#xff09;&#xff0c;并且在命令行ping不通该Linux虚拟机的IP地址。下面通过配置网关解决本地与Linux虚拟机连接问题&#xff1a; 1 查看虚拟机网关地址 在VMware虚拟机上…...

每日JAVA高级面试题

Java 高级面试问题及答案 以下是几个Java高级面试中可能会问到的问题&#xff0c;包括问题、答案以及一些探讨过程。 问题1: 请解释Java中的多线程以及线程池的使用场景和优势 答案&#xff1a; Java中的多线程允许程序执行多个任务&#xff0c;从而提高应用程序的响应速度和…...

修改JupyterNotebook文件存储位置

Jupyter Notebook 1、通过AnaConda安装Jupyter Notebok 2、在开始菜单里找到并打开Anaconda Prompt&#xff0c;输入如下命令&#xff0c;然后执行。 jupyter notebook --generate-config4、打开以下文件 找到 C:/Userzh/.../.jupyter 打开 jupyter_notebook_config.py 取消…...

python Flask路由系统如何影响应用性能的一些关键点

Flask的路由系统对应用性能的影响主要体现在路由匹配和分发请求的效率上。以下是关于Flask路由系统如何影响应用性能的一些关键点&#xff1a; 路由匹配方式&#xff1a;Flask支持精准匹配和模糊匹配两种方式。精准匹配是指URL中的路径和定义的路由规则完全匹配&#xff0c;而…...

nodejs的ws+vue3编写聊天室的demo

nodejs编写ws服务是非常简单高效的&#xff0c;nodejs有众多的实现ws的库&#xff0c;如ws,SocketIO等&#xff0c;nodejs的事件线程是单线程的&#xff0c;所以不要在事件线程内做阻塞性的操作&#xff0c;耗时的操作交给工作线程或者子进程操作。 我使用nodejsvue3实现了写了…...

《MySQL数据类型》

文章目录 一、理解数据本身就是一种约束1.tinyint类型和 tinyint unsigned类型2.其他的int类型 二、bit类型三、float类型1.signed版本注意2.unsigned版本 四、decimal类型float 和 decimal 总结五、char类型&#xff08;固定长度&#xff09;六、varchar类型&#xff08;可变长…...

解决windows中的WSL Ubuntu子系统忘记root密码和用户密码问题

1、以管理员身份运行PowerShell 2、在powershell中执行wsl.exe --user root wsl.exe --user root如果出现了上面的报错&#xff0c;则需要运行步骤3、4&#xff0c;然后在执行步骤5改密码&#xff0c;如果没有出错&#xff0c;请直接跳到第5步改密码操作&#xff01;&#xff…...

【Oracle APEX开发小技巧12】

有如下需求&#xff1a; 有一个问题反馈页面&#xff0c;要实现在apex页面展示能直观看到反馈时间超过7天未处理的数据&#xff0c;方便管理员及时处理反馈。 我的方法&#xff1a;直接将逻辑写在SQL中&#xff0c;这样可以直接在页面展示 完整代码&#xff1a; SELECTSF.FE…...

三维GIS开发cesium智慧地铁教程(5)Cesium相机控制

一、环境搭建 <script src"../cesium1.99/Build/Cesium/Cesium.js"></script> <link rel"stylesheet" href"../cesium1.99/Build/Cesium/Widgets/widgets.css"> 关键配置点&#xff1a; 路径验证&#xff1a;确保相对路径.…...

YSYX学习记录(八)

C语言&#xff0c;练习0&#xff1a; 先创建一个文件夹&#xff0c;我用的是物理机&#xff1a; 安装build-essential 练习1&#xff1a; 我注释掉了 #include <stdio.h> 出现下面错误 在你的文本编辑器中打开ex1文件&#xff0c;随机修改或删除一部分&#xff0c;之后…...

CMake控制VS2022项目文件分组

我们可以通过 CMake 控制源文件的组织结构,使它们在 VS 解决方案资源管理器中以“组”(Filter)的形式进行分类展示。 🎯 目标 通过 CMake 脚本将 .cpp、.h 等源文件分组显示在 Visual Studio 2022 的解决方案资源管理器中。 ✅ 支持的方法汇总(共4种) 方法描述是否推荐…...

中医有效性探讨

文章目录 西医是如何发展到以生物化学为药理基础的现代医学&#xff1f;传统医学奠基期&#xff08;远古 - 17 世纪&#xff09;近代医学转型期&#xff08;17 世纪 - 19 世纪末&#xff09;​现代医学成熟期&#xff08;20世纪至今&#xff09; 中医的源远流长和一脉相承远古至…...

技术栈RabbitMq的介绍和使用

目录 1. 什么是消息队列&#xff1f;2. 消息队列的优点3. RabbitMQ 消息队列概述4. RabbitMQ 安装5. Exchange 四种类型5.1 direct 精准匹配5.2 fanout 广播5.3 topic 正则匹配 6. RabbitMQ 队列模式6.1 简单队列模式6.2 工作队列模式6.3 发布/订阅模式6.4 路由模式6.5 主题模式…...

pycharm 设置环境出错

pycharm 设置环境出错 pycharm 新建项目&#xff0c;设置虚拟环境&#xff0c;出错 pycharm 出错 Cannot open Local Failed to start [powershell.exe, -NoExit, -ExecutionPolicy, Bypass, -File, C:\Program Files\JetBrains\PyCharm 2024.1.3\plugins\terminal\shell-int…...

React从基础入门到高级实战:React 实战项目 - 项目五:微前端与模块化架构

React 实战项目&#xff1a;微前端与模块化架构 欢迎来到 React 开发教程专栏 的第 30 篇&#xff01;在前 29 篇文章中&#xff0c;我们从 React 的基础概念逐步深入到高级技巧&#xff0c;涵盖了组件设计、状态管理、路由配置、性能优化和企业级应用等核心内容。这一次&…...

[拓扑优化] 1.概述

常见的拓扑优化方法有&#xff1a;均匀化法、变密度法、渐进结构优化法、水平集法、移动可变形组件法等。 常见的数值计算方法有&#xff1a;有限元法、有限差分法、边界元法、离散元法、无网格法、扩展有限元法、等几何分析等。 将上述数值计算方法与拓扑优化方法结合&#…...

基于 HTTP 的单向流式通信协议SSE详解

SSE&#xff08;Server-Sent Events&#xff09;详解 &#x1f9e0; 什么是 SSE&#xff1f; SSE&#xff08;Server-Sent Events&#xff09; 是 HTML5 标准中定义的一种通信机制&#xff0c;它允许服务器主动将事件推送给客户端&#xff08;浏览器&#xff09;。与传统的 H…...