设计模式——建造者模式(Builder Pattern)

概述

       建造者模式是较为复杂的创建型模式,它将客户端与包含多个组成部分(或部件)的复杂对象的创建过程分离,客户端无须知道复杂对象的内部组成部分与装配方式,只需要知道所需建造者的类型即可。它关注如何一步一步创建一个的复杂对象,不同的具体建造者定义了不同的创建过程,且具体建造者相互独立,增加新的建造者非常方便,无须修改已有代码,系统具有较好的扩展性。建造者模式定义如下:建造者模式(Builder Pattern):将一个复杂对象的构建与它的表示分离,使得同样的构建过程可以创建不同的表示。建造者模式是一种对象创建型模式。

      建造者模式一步一步创建一个复杂的对象,它允许用户只通过指定复杂对象的类型和内容就可以构建它们,用户不需要知道内部的具体构建细节。建造者模式结构如图所示:

在建造者模式结构图中包含如下几个角色:

● Builder(抽象建造者):它为创建一个产品Product对象的各个部件指定抽象接口,在该接口中一般声明两类方法,一类方法是buildPartX(),它们用于创建复杂对象的各个部件;另一类方法是getResult(),它们用于返回复杂对象。Builder既可以是抽象类,也可以是接口。

●ConcreteBuilder(具体建造者):它实现了Builder接口,实现各个部件的具体构造和装配方法,定义并明确它所创建的复杂对象,也可以提供一个方法返回创建好的复杂产品对象。

●Product(产品角色):它是被构建的复杂对象,包含多个组成部件,具体建造者创建该产品的内部表示并定义它的装配过程。

● Director(指挥者):指挥者又称为导演类,它负责安排复杂对象的建造次序,指挥者与抽象建造者之间存在关联关系,可以在其construct()建造方法中调用建造者对象的部件构造与装配方法,完成复杂对象的建造。客户端一般只需要与指挥者进行交互,在客户端确定具体建造者的类型,并实例化具体建造者对象(也可以通过配置文件和反射机制),然后通过指挥者类的构造函数或者Setter方法将该对象传入指挥者类中。

简单实现
常规实现

编写测试代码并运行:

       上面示例是建造者模式的常规用法,指挥者类ComputerDirector在建造者模式中具有很重要的作用,它用于指导具体构建者如何构建产品,控制调用先后次序,并向调用者返回完整的产品类,但是有些情况下需要简化系统结构,可以把指挥者类和抽象建造者进行结合,于是就有了下面的简化写法。

简化实现

编写测试代码并运行:

       可以看到,对比常规写法,这样写确实简化了系统结构,但同时也加重了建造者类的职责,也不是太符合单一职责原则,如果construct() 过于复杂,建议还是封装到 Director 中。

链式实现

       可以看到,其实链式写法与普通写法的区别并不大,只是在建造者类组装部件的时候,同时将建造者类返回即可,使用链式写法使用起来更方便,某种程度上也可以提高开发效率。从软件设计上,对程序员的要求比较高。比较常见的mybatis-plus中的条件构造器就是使用的这种链式写法。

钩子方法

       建造者模式除了逐步构建一个复杂产品对象外,还可以通过Director类来更加精细地控制产品的创建过程,例如增加一类称之为钩子方法(HookMethod)的特殊方法来控制是否对某个buildPartX()的调用。

       钩子方法的返回类型通常为boolean类型,方法名一般为isXXX(),钩子方法定义在抽象建造者类中。例如我们可以在组装电脑的的抽象建造者类ComputerBuilder中定义一个方法isGpu(),用于判断某个电脑是否需要组装Gpu,在ComputerBuilder为之提供一个默认实现,其返回值为false,代码如下所示:

       如果某个电脑无需组装Gpu,则对应的具体建造者将覆盖isGpu()方法,并设置值为true,代码如下:

       此时。指挥者类ComputerDirector代码修改如下:

运行如下:

       上图可以看出,Gpu是null,没有组装上去,通过引入钩子方法,我们可以在Director中对复杂产品的构建进行精细的控制,不仅指定buildPartX()方法的执行顺序,还可以控制是否需要执行某个buildPartX()方法。

总结

       建造者模式与抽象工厂模式有点相似,但是建造者模式返回一个完整的复杂产品,而抽象工厂模式返回一系列相关的产品;在抽象工厂模式中,客户端通过选择具体工厂来生成所需对象,而在建造者模式中,客户端通过指定具体建造者类型并指导Director类如何去生成对象,侧重于一步步构造一个复杂对象,然后将结果返回。如果将抽象工厂模式看成一个汽车配件生产厂,生成不同类型的汽车配件,那么建造者模式就是一个汽车组装厂,通过对配件进行组装返回一辆完整的汽车。建造者模式的核心在于如何一步步构建一个包含多个组成部件的完整对象,使用相同的构建过程构建不同的产品,在软件开发中,如果我们需要创建复杂对象并希望系统具备很好的灵活性和可扩展性可以考虑使用建造者模式。

1.主要优点

建造者模式的主要优点如下:

(1) 在建造者模式中,客户端不必知道产品内部组成的细节,将产品本身与产品的创建过程解耦,使得相同的创建过程可以创建不同的产品对象。

(2) 每一个具体建造者都相对独立,而与其他的具体建造者无关,因此可以很方便地替换具体建造者或增加新的具体建造者,用户使用不同的具体建造者即可得到不同的产品对象。由于指挥者类针对抽象建造者编程,增加新的具体建造者无须修改原有类库的代码,系统扩展方便,符合“开闭原则”

(3) 可以更加精细地控制产品的创建过程。将复杂产品的创建步骤分解在不同的方法中,使得创建过程更加清晰,也更方便使用程序来控制创建过程。

2.主要缺点

建造者模式的主要缺点如下:

(1) 建造者模式所创建的产品一般具有较多的共同点,其组成部分相似,如果产品之间的差异性很大,例如很多组成部分都不相同,不适合使用建造者模式,因此其使用范围受到一定的限制。

(2) 如果产品的内部变化复杂,可能会导致需要定义很多具体建造者类来实现这种变化,导致系统变得很庞大,增加系统的理解难度和运行成本。

3.适用场景

在以下情况下可以考虑使用建造者模式:

(1) 需要生成的产品对象有复杂的内部结构,这些产品对象通常包含多个成员属性。

(2) 需要生成的产品对象的属性相互依赖,需要指定其生成顺序。

(3) 对象的创建过程独立于创建该对象的类。在建造者模式中通过引入了指挥者类,将创建过程封装在指挥者类中,而不在建造者类和客户类中。

(4) 隔离复杂对象的创建和使用,并使得相同的创建过程可以创建不同的产品。

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

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

相关文章

09 STM32 - PWM

9.1 PWM简介 脉冲宽度调制(Pulse Width Modulation,简称PWM),是利用微处理器的数字输出来对模拟电路进行控制的一种非常有效的技术。简单一点,就是对脉冲宽度的控制。 9.2 PWM波原理 如下图所示,使用定时器定时,从0开始&#x…

Ubuntu系统Git的安装配置及使用笔记(更新中)

Ubuntu下Git的下载及配置 (1)、下载git 打开终端命令窗口,输入:sudo apt-get install git 提示:sudo命令是用来以其他身份来执行命令,预设的身份为root,使用sudo时必须先输入密码 (2)、可以使用命令git --version查看git的版本号 (3)、设置…

项目中常用的ahoos

项目中常用的ahoos如下 useMount、useUnmountuseRequestuseBooleanuseInfiniteScrolluseLocalStorageStateuseInViewportuseUpdateEffectuseLayoutEffectuseMapuseThrottleFnuseDebounceFn

Java内置锁:深度解析StampedLock并发类

内容摘要 StampedLock类是一种高性能的读写锁,它通过引入乐观读和写锁的优化机制,提高了多线程环境下的并发性能,他支持三种访问模式:悲观读、写和乐观读,可以根据不同的业务场景选择适合的锁策略,相比传统…

Qt/QML编程之路:OpenGL的示例(39)

Qt编程之后,会发现有版本问题,有时候一个示例不同的版本下可能会跑不同,有些Qt5跑不同Qt6已经完善,可以跑通。 我就看到有个关于OpenGL的示例: 这个示例是演示怎么基于OpenGL编程的,但是调试时却发现glViewXXX等gl打头的函数说找不到reference,或者什么link不上之类的错…

FindMy技术与游戏手柄结合

游戏手柄作为游戏的重要配件,它极大地提升了玩家的游戏体验,推动了游戏市场的不断扩大。游戏手柄的触摸感应技术为游戏开发者提供了更多的创意空间,也为硬件制造商带来了新的商机。游戏手柄的个性化定制也为玩家社区的发展提供了动力&#xf…

红队打靶练习:BOB: 1.0.1

目录 信息收集 1、netdiscover 2、nmap 3、nikto 4、whatweb 目录探测 1、dirb 2、gobuster 3、dirsearch WEB 主页: robots.txt 其他页面 反弹shell 提权 系统信息收集 jc账户 本地提权 信息收集 1、netdiscover ┌──(root㉿ru)-[~/kali] └…

命令执行拼接符实例图解

命令执行常用到的5个拼接符,分别是逻辑与(&&)、逻辑或(||)、按位与(&)、按位或(|)和linux系统特有的分号(;) 1、&&&#xf…

运维平台介绍:视频智能运维平台的视频质量诊断分析和告警中心

目 录 一、视频智能运维平台介绍 (一)平台概述 (二)结构图 (三)功能介绍 1、运维监控 2、视频诊断 3、巡检管理 4、告警管理 5、资产管理 6、工单管理 7、运维…

【C++干货铺】C++11常用新特性 | 列表初始化 | STL中的变化

个人主页点击直达:小白不是程序媛 C系列专栏:C干货铺 代码仓库:Gitee 目录 C11简介 列表初始化 std::initializer_list std::initializer_list使用场景 decltype关键字 STL中的一些变化 新容器 array forward_list 容器中的一些新…

chrony介绍和安装

chrony介绍和安装 1.chrony(时间同步服务) 1.1 chrony介绍 Chrony 是一个用于时间同步的软件,它旨在提供高精度的系统时钟同步。Chrony 软件包括一个 NTP(Network Time Protocol,网络时间协议)服务器和客…

Python基础第二篇(Python基础语法)

文章目录 一、字面量二、注释三、变量四、数据类型五、数据类型转换六、标识符七、运算符八、字符串扩展内容(1)字符串定义(2)字符串拼接、(3)字符串格式化(4)字符串格式化的精度控制…

【算法与数据结构】Java实现查找与排序

文章目录 第一部分:查找算法二分查找插值查找分块查找哈希查找树表查找 第二部分:排序算法冒泡排序选择排序插入排序快速排序 总结 第一部分:查找算法 二分查找 也叫做折半查找,属于有序查找算法。 前提条件:数组数据…

TestNG注释

目录 TestNG注释列表 BeforeXXX和AfterXXX注释放在超类上时如何工作? 使用BeforeXXX和AfterXXX TestNG注释 TestNG是一个测试框架,旨在简化广泛的测试需求,从单元测试(隔离测试一个类)到集成测试(测试由…

某马头条——day05

文章定时发布 实现方案对比 实现方案 延迟队列服务实现 按照文档进行项目的导入并准备数据库表导入对应实体类和nacos配置中心 乐观锁集成 redis集成和测试 成功集成通过测试 添加任务 ①:拷贝mybatis-plus生成的文件,mapper ②:创建task类…

ConcurrentHashMap 原理

ConcurrentHashMap ConcurrentHashMap的整体架构ConcurrentHashMap的基本功能ConcurrentHashMap在性能方面的优化 concurrentHashMap: ConcurrentHashMap的整体架构 concurrentHashMap是由数组链表红黑树组成 当我们初始化一个ConcurrentHashMap实例时&#xff0c…

基于74LS191+74LS160的8位二进制转BCD码应用电路设计

一、74LS191简介: 74LS191为可预置的四位二进制加/减法计数器,RCO进位/借位输出端,MAX/MIN进位/借位输出端,CTEN计数控制端,QA-QD计数输出端,U/D计数控制端,CLK时钟输入端,LOAD异步并行置入端(低电平有效)。 二、74LS191功能表: 三、74LS191逻辑框图: 四、74LS160…

2024美赛数学建模思路 - 案例:异常检测

文章目录 赛题思路一、简介 -- 关于异常检测异常检测监督学习 二、异常检测算法2. 箱线图分析3. 基于距离/密度4. 基于划分思想 建模资料 赛题思路 (赛题出来以后第一时间在CSDN分享) https://blog.csdn.net/dc_sinor?typeblog 一、简介 – 关于异常…

2024年【裂解(裂化)工艺】考试题及裂解(裂化)工艺免费试题

题库来源:安全生产模拟考试一点通公众号小程序 裂解(裂化)工艺考试题参考答案及裂解(裂化)工艺考试试题解析是安全生产模拟考试一点通题库老师及裂解(裂化)工艺操作证已考过的学员汇总&#xf…

CentOS7 配置静态IP

目录 在解决了刚安装不能联网后配置静态IP1.查看配置好网卡后,DHCP动态分配的IP地址2. 查看网关3. 更改IP地址文件4. 重启网络服务5. 检查配置6. 更新路由(如果需要) 在解决了刚安装不能联网后 解决centos 7刚安装不能联网 配置静态IP 在 C…