设计模式之建造者(Builder)模式

目录

1、什么是建造者Builder模式?

2、建造者Builder模式的利与弊

3、建造者Builder模式的应用场景

4、建造者模式中的指导者(Director)有什么作用?

5、建造者Builder模式与其他模式的关系

小结


1、什么是建造者Builder模式?

Builder模式是一种创建型设计模式,用于将复杂对象的构建过程和表示分离,使得同样的构建过程可以创建不同的表示。建造者模式又称为生成器模式,主要用于对复杂对象的构建及初始化,它可以将多个简单的组件对象按顺序一步步组装起来,最终完成一个复杂的成品对象。与工厂系列模式不同的是,建造者模式的主要目的在于把烦琐的构建过程从不同对象中抽离出来,使其脱离并独立于产品类与工厂类,最终实现用同一套标准的制造工序能够产出不同的产品

在生活中,一个常见的例子是建筑领域的房屋建造。我们可以将房屋的建造过程看作是使用Builder模式来创建房屋对象的过程。

假设我们需要建造一座房子,房子由多个组成部分(例如地基、楼层、墙壁、窗户等)组成,并且每个部分都有多个属性(例如地基的深度、楼层的高度、墙壁的材料等)。

使用Builder模式,我们可以定义一个HouseBuilder类作为建造者,它负责创建和组装房子的各个部分。HouseBuilder类可以有一些方法来设置房子的各个属性,例如setFoundationDepth(int depth)、setFloorHeight(int height)等。

另外,我们还可以定义一个House类作为最终构建的产品。House类包含了房子的所有属性,并提供了访问这些属性的方法。

下面是一个简化的示例代码:

// 房子类
public class House {private int foundationDepth;private int floorHeight;private String wallMaterial;// 构造函数和访问方法省略// ...
}// 建造者类
public class HouseBuilder {private House house;public HouseBuilder() {house = new House();}public void setFoundationDepth(int depth) {house.setFoundationDepth(depth);}public void setFloorHeight(int height) {house.setFloorHeight(height);}public void setWallMaterial(String material) {house.setWallMaterial(material);}public House build() {return house;}
}// 使用Builder模式创建房子对象
public class Main {public static void main(String[] args) {HouseBuilder builder = new HouseBuilder();builder.setFoundationDepth(10);builder.setFloorHeight(3);builder.setWallMaterial("Brick");House house = builder.build();// 使用房子对象进行后续操作// ...}
}

在上述示例中,HouseBuilder类负责创建和设置房子的各个属性,最后通过build()方法返回构建好的House对象。这样,我们可以根据需要灵活地设置房子的各个部分,并且可以通过调用build()方法来获取最终的房子对象。

建造者模式的结构图示:

图片来源:设计模式-生成器(Builder) - 知乎

 图片来源:设计模式-生成器(Builder) - 知乎

2、建造者Builder模式的利与弊

Builder模式具有以下优点

  1. 隔离复杂对象的构建过程:Builder模式将复杂对象的构建过程与其表示分离,使得可以独立地构建不同表示的对象。这样可以简化构建过程,提高可读性和维护性。

  2. 提供灵活的构建方式:通过定义不同的Builder或者使用方法链式调用,可以按需设置对象的各个属性,从而灵活地构建对象。可以根据需要组合不同的属性,生成不同的对象实例。

  3. 支持构建过程的逐步完善:Builder模式可以支持逐步完善构建过程,即在Builder中逐步添加设置方法,最后调用build方法返回最终的对象。这种方式可以方便地扩展构建过程,适应不同的需求。

  4. 避免构造函数参数过多:当一个类的构造函数参数过多时,使用Builder模式可以避免构造函数的参数列表过长,提高代码的可读性。

Builder模式的一些缺点

  1. 增加了类的复杂度:引入了Builder类和多个setter方法,增加了类的复杂度和代码量。

  2. 对象构建过程的冗余:Builder模式会创建一个Builder对象来构建目标对象,可能会导致额外的对象创建开销。

  3. 不适用于简单对象:如果目标对象的属性较少,构建过程相对简单,使用Builder模式可能不是最优选择,会增加代码量和复杂度。

需要根据具体情况来权衡使用Builder模式的利弊。在复杂对象的构建过程中,特别是当对象具有大量属性或者构建过程需要逐步完善时,Builder模式可以提供一种灵活、可读性高的解决方案。

3、建造者Builder模式的应用场景

  1. 构建复杂对象:当需要构建的对象具有多个属性,并且构建过程较为复杂时,可以考虑使用Builder模式。例如,构建包含大量配置选项的文档生成器、图形界面中的复杂组件等。

  2. 避免重叠构造函数:当一个类需要多个构造函数来支持不同的对象初始化方式时,可以使用Builder模式来避免创建过多的重叠构造函数,并提供更清晰的对象构建方法。

  3. 创建不可变对象:当需要创建不可变(Immutable)对象时,Builder模式可以很好地与不可变对象的设计原则结合,通过Builder来设置对象的属性,最终构建出不可变的对象实例。

  4. 流式接口(Fluent Interface):Builder模式可以用于创建流式接口,使得客户端代码可以使用链式调用的方式来设置对象的属性,从而提高代码的可读性和简洁性。

  5. 多个构建过程:当需要支持多种构建过程,或者需要逐步完善构建过程时,Builder模式可以提供一种灵活的解决方案,支持根据不同需求构建不同表示的对象。

总的来说,Builder模式适用于需要构建复杂对象、有多个可选参数或需要逐步完善构建过程的情况。通过使用Builder模式,可以将对象的构建过程分离出来,提高灵活性和可读性。

4、建造者模式中的指导者(Director)有什么作用?

在建造者模式中,指导者(Director)起到了协调和组织的作用。它负责控制构建过程,按照特定的顺序调用建造者的方法来构建对象。

指导者的主要作用有以下几点:

  1. 定义构建顺序:指导者确定了构建过程中各个步骤的顺序和调用方式。它知道哪些方法应该在何时被调用,以保证对象的正确构建。

  2. 解耦客户端与具体构建过程:指导者将构建对象的过程封装起来,并与具体的建造者解耦。客户端不需要直接与建造者进行交互,而是通过指导者来完成对象的构建。

  3. 简化客户端代码:指导者隐藏了构建细节,使得客户端可以更简洁地调用构建过程。客户端只需要与指导者进行交互,并传递必要的参数,而无需关心具体的构建过程。

指导者的实现原理通常是通过将建造者作为参数进行注入,并在内部调用建造者的方法来完成构建过程。指导者根据具体需求和建造者的能力来决定调用哪些方法以及调用顺序。

具体实现上,指导者可以提供一个统一的构建方法,接收建造者作为参数,并按照预定的顺序调用建造者的方法来构建对象。也可以根据需要提供一系列的构建方法,每个方法负责调用建造者的特定方法,以完成特定的构建步骤。

通过指导者的存在,客户端可以更简单地调用构建方法,而无需关心具体的构建细节和顺序,从而实现了构建过程的解耦和简化。

5、建造者Builder模式与其他模式的关系

该片段引自:Builder

1. 许多设计从使用Factory方法(不那么复杂,通过子类更可定制)开始,并向抽象工厂、原型或生成器(更灵活,但更复杂)发展。
2. Builder专注于逐步构建复杂的对象。抽象工厂专门创建相关对象的族。Abstract Factory会立即返回产品,而Builder允许在获取产品之前运行一些额外的构造步骤
3. 在创建复杂的复合树时可以使用Builder,因为可以对其构建步骤进行编程以递归工作。
4. 您可以将Builder和Bridge结合起来:director类扮演抽象的角色,而不同的构建器充当实现。
5. 抽象工厂、构建者和原型都可以实现为Singleton。

小结

Builder 模式的关键是其中的 Director 对象并不直接返回对象,而是通过分步进行对象的创建。在这里 Director 可以提供一个默认的返回对象的接口(即返回通用的复杂对象的创建,不指定或者特定唯一指定BuildPart中的参数)。

通过使用Builder模式,可以避免在构造函数或者setter方法中传入大量参数,并且可以更加清晰地组织和管理复杂对象的构建过程。

参考:

精讲设计模式-Builder模式-CSDN博客

设计模式-生成器(Builder) - 知乎

大白话建造者模式(Builder Pattern) - 张有路 - 博客园

Builder

设计模式系列3 - builder模式 - 知乎


感谢阅读,码字不易,多谢点赞!如有不当之处,欢迎反馈指出,感谢!

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.mzph.cn/news/166125.shtml

如若内容造成侵权/违法违规/事实不符,请联系多彩编程网进行投诉反馈email:809451989@qq.com,一经查实,立即删除!

相关文章

百分点科技入选《2023年央国企数字化升级研究报告》

近日,艾瑞咨询发布了《2023年央国企数字化升级研究报告》,报告总结了央国企数字化升级的方向和特点,并重点研究了基础平台及关键技术工具、通用及综合型应用、重要配套建设等方面。报告指出,数据治理是央国企数字化升级过程中的重…

【鸿蒙应用ArkTS开发系列】- 云开发入门实战二 实现省市地区三级联动地址选择器组件(上)

目录 概述 云数据库开发 一、创建云数据库的对象类型。 二、预置数据(为对象类型添加数据条目)。 三、部署云数据库 云函数实现业务逻辑 一、创建云函数 二、云函数目录讲解 三、创建resources目录 四、获取云端凭据 五、导出之前创建的元数据…

HTML新手入门笔记整理:特殊符号

音标符 音标符 字符 Construct 输出结果 ̀、 a a à ́′ a a án ˆ a a â ̃&#xff5e; a a ã ̀̀、 O O Ò ́́′ O O Ó ˆ O O Ô ̃&#xff5e; O O Õ 字符 显示结果 描述 实体名称 实体编号 空格 <…

【数据结构】F : 道路建设 (Ver. I)

F : 道路建设 (Ver. I) Description 有N个村庄&#xff0c;编号从1到N&#xff0c;你应该建造一些道路&#xff0c;使每个村庄都可以相互连接。 两个村A和B是相连的&#xff0c;当且仅当A和B之间有一条道路&#xff0c;或者存在一个村C使得在A和C之间有一条道路&#xff0c;并…

编程实例,随机抽奖编程

编程实例&#xff0c;随机抽奖编程 操作步骤&#xff1a; 1、将在本店消费的会员数据导入到抽奖池&#xff0c;可以设定最近多少天内的记录。 2、点击 开始随机抽奖&#xff0c;软件将从抽奖池随机抽取9名&#xff0c;并不断变化&#xff0c;每0.02秒重新随机抽取9名显示到屏…

Java 项目中常用注解汇总!! (自整理)

Spring框架的注解 PostMapping("/getDetails") post请求 映射到接口 RequestBody 用来接收HTTP请求体中参数 GetMapping("/getDetails") get请求 映射到接口 RequestParam 用来接收URL中的查询参数 PutMappi…

7:kotlin 数组 (Arrays)

数组是一种数据结构&#xff0c;它保存固定数量的相同类型或其子类型的值。kotlin中最常见的数组类型是对象类型数组&#xff0c;数组由array类表示。 什么时候使用 当你在kotlin中有特殊的底层需求需要满足时&#xff0c;可以使用数组。例如&#xff0c;如果你有超出常规应用…

关于js的find的基本用法

Array.prototype.find() 是 JavaScript 的一个数组方法&#xff0c;它被用来在数组中查找一个符合条件的元素。一旦找到第一个符合条件的元素, find() 会立即返回这个元素的值&#xff0c;否则返回 undefined。 以下是 find() 方法的基本语法&#xff1a; arr.find(callback(el…

​LeetCode解法汇总1410. HTML 实体解析器

目录链接&#xff1a; 力扣编程题-解法汇总_分享记录-CSDN博客 GitHub同步刷题项目&#xff1a; https://github.com/September26/java-algorithms 原题链接&#xff1a;力扣&#xff08;LeetCode&#xff09;官网 - 全球极客挚爱的技术成长平台 描述&#xff1a; 「HTML 实…

利用企业被执行人信息查询API保障商业交易安全

前言 在当今竞争激烈的商业环境中&#xff0c;企业为了保障商业交易的安全性不断寻求新的手段。随着技术的发展&#xff0c;利用企业被执行人信息查询API已经成为了一种强有力的工具&#xff0c;能够帮助企业在商业交易中降低风险&#xff0c;提高合作的信任度。 企业被执行人…

如何使用 JavaScript 实现图片上传并转换为 LaTeX 公式

在本教程中&#xff0c;我们将学习如何使用 JavaScript 创建一个上传图片的功能&#xff0c;并将所选图片转换为 LaTeX 公式。我们将使用 FileReader 对象来读取图片并将其转换为 Base64 格式&#xff0c;然后利用 img2latex API 将其转换为 LaTeX 公式。 1. HTML 结构 首先&…

SpringMVC日志追踪笔记整理

新建logback-spring.xml <?xml version"1.0" encoding"UTF-8"?> <configuration><property name"PATH" value"./log/business"></property><appender name"STDOUT" class"ch.qos.logback…

linux进程调度(三)-进程终止

文章目录 2.3 进程退出的几种情况2.4 进程终止过程分析2.4.1 exit_notify函数2.4.1.1 forget_original_parent函数2.4.1.1.1 find_child_reaper函数2.4.1.1.2 find_new_reaper函数2.4.1.1.3 reparent_leader函数 2.4.1.2 do_notify_parent函数2.4.1.3 release_task函数 2.4.2 d…

GitHub桌面版

GitHub桌面版 一、GitHub 桌面版二、clone 仓库三、更新仓库 一、GitHub 桌面版 二、clone 仓库 三、更新仓库

穆桂英挂帅

《穆桂英挂帅》 作家&#xff0f;罗光记 穆桂英挂帅破敌&#xff0c; 威风凛凛立战场。 铁甲如云奔雷急&#xff0c; 英姿飒爽傲寒霜。 烽火连天战鼓擂&#xff0c; 旌旗翻飞壮心惊。 刀光剑影映红日&#xff0c; 豪情壮志天地惊。 风云变幻战事急&#xff0c; 英勇穆桂英…

Azure Machine Learning - Azure可视化图像分类操作实战

目录 一、数据准备二、创建自定义视觉资源三、创建新项目四、选择训练图像五、上传和标记图像六、训练分类器七、评估分类器概率阈值 八、管理训练迭代 在本文中&#xff0c;你将了解如何使用Azure可视化页面创建图像分类模型。 生成模型后&#xff0c;可以使用新图像测试该模型…

温馨提示!办理流量卡千万不要填写别人的身份证信息,切记!

可以用别人的身份证办理流量卡吗&#xff1f;是很多朋友都比较关注的一个问题&#xff0c;在这里明确的告诉大家一下&#xff0c;当然是不可以的。 ​  不管你是在线下营业厅办理&#xff0c;还是在线上申请&#xff0c;都是需要提供本人的证件信息才能办理&#xff1a; 1、…

TIDB拓扑结构

TiDB Server&#xff1a;SQL层&#xff0c;负责接受客户端的连接&#xff0c;执行SQL解析和优化&#xff0c;最终生成分布式执行计划。TiDB Server为无状态的&#xff0c;可增加节点负载均衡。 PD (Placement Driver) Server&#xff1a;整个TiDB集群的元信息管理模块&#xf…

【超详细】手搓一个微信日记本

&#x1f380; 文章作者&#xff1a;二土电子 &#x1f338; 关注公众号获取更多资料&#xff01; &#x1f438; 期待大家一起学习交流&#xff01; 这里对之前的微信记事本小程序进行了重新编写&#xff0c;增加了更加详细的步骤描述&#xff0c;将全部图片都改成了本地图…

用EasyAVFilter将网络文件或者本地文件推送RTMP出去的时候发现CPU占用好高,用的也是vcodec copy呀,什么原因?

最近同事在用EasyAVFilter集成在EasyDarwin中做视频拉流转推RTMP流的功能的时候&#xff0c;发现怎么做CPU占用都会很高&#xff0c;但是视频没有调用转码&#xff0c;vcodec用的就是copy&#xff0c;这是什么原因呢&#xff1f; 我们用在线的RTSP流就不会出现这种情况&#x…