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

news2024/9/26 3:23:28
概述

       建造者模式是较为复杂的创建型模式,它将客户端与包含多个组成部分(或部件)的复杂对象的创建过程分离,客户端无须知道复杂对象的内部组成部分与装配方式,只需要知道所需建造者的类型即可。它关注如何一步一步创建一个的复杂对象,不同的具体建造者定义了不同的创建过程,且具体建造者相互独立,增加新的建造者非常方便,无须修改已有代码,系统具有较好的扩展性。建造者模式定义如下:建造者模式(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.coloradmin.cn/o/1397015.html

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

相关文章

LLaVA-Plus:多模态大模型的新突破

前言 随着AIGC技术的不断进步,各类多模态大模型(MLM)开始蓬勃发展。在这一领域中,LLaVA-Plus的推出无疑是一次重大突破。作为LLaVA团队的最新工作,LLaVA-Plus不仅继承了LLaVA的优秀特性,还在此基础上进行了…

【方法】如何合并多个PDF文件?

多个PDF文件,想合并成一个文件,要怎么操作呢? 如果PDF文件的数量少,并且页数也不多,可以试试将内容复制黏贴到Word文档,再转为PDF格式;如果文件数量多,页数也多,就不太合…

机器人强化学习-双机械臂

概要 基于 robosuite 库,进行双臂机器人学习训练 环境测试 下面展示下分别控制两个机械手随机运动的画面: 双臂显示场景如下:双臂调用代码如下: import numpy as np import robosuite as suite import robomimic import rob…

【音视频原理】图像相关概念 ③ ( RGB 色彩简介 | RGB 排列 | YUV 色彩简介 | YUV 编码好处 )

文章目录 一、RGB 色彩1、RGB 色彩简介2、RGB 排列 二、YUV 色彩1、YUV 色彩简介2、YUV 编码好处 一、RGB 色彩 1、RGB 色彩简介 RGB 是 计算机 中的 颜色编码方法 , 红 ( R ) / 绿 ( G ) / 蓝 ( B ) 三个颜色通道 可以设置不同的值 , 每个 通道 的 颜色值都可以取值 0 ~ 255 ,…

深度学习模型之yolov8实例分割模型TesorRT部署-python版本

1 模型转换 从github上下载官方yolov8版本,当前使用的版本是2023年9月份更新的版本,作者一直在更新。官网地址 2 加载模型 模型的训练和测试在官方文档上,有详细的说明,yolov8中文文档这里不做过多说明,v8现在训练是…

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

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

ChatGPT给出的前端面试考点(Vue.js)

ChatGPT给出的前端面试考点(Vue.js) 答案 1. Vue.js是什么?它的主要特点是什么? Vue.js是一个渐进式JavaScript框架,用于构建用户界面。它的主要特点包括: 数据绑定:Vue.js使用双向数据绑定&…

anaconda镜像源,查看镜像,删除镜像,添加镜像

查看镜像配置: conda config --show channel 对应的就是我们的镜像配置 删除旧镜像源 conda config --remove channels https://mirrors.tuna.tsinghua.edu.cn/anaconda/pkgs/free/ 添加新镜像源: conda config --add channels https://mirrors.tu…

Next.js 开发指​南(GitHub 115k star​)

Next.js 是一个构建于 Node.js 之上的开源 Web 开发框架,它扩展了最新的 React 特性,集成了基于 Rust 的 JavaScript 工具,可以帮助你快速创建全栈 Web 应用 (full-stack Web applications) 。 对于有一定 React 基础…

TQ8WS-acid,Tide Quencher 8WS-酸,可用来研究荧光物质的激发态

您好,欢迎来到新研之家 文章关键词:Tide Quencher8WS acid,TQ8WS acid,Tide Quencher 8WS 酸 ,TQ8WS 酸,Tide Quencher 8WS-酸,TQ8WS-酸 一、基本信息 产品简介:The fluorescence…

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

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

Yearning存在任意文件读取漏洞

文章目录 前言声明一、Yearning简介二、漏洞描述三、影响版本四、漏洞复现五、修复建议 前言 Yearning MYSQL SQL语句审核平台。提供查询审计,SQL审核,SQL回滚,自定义工作流等多种功能。该平台存在任意文件读取漏洞。 声明 请勿利用文章内的…

OpenCV-Python(44):对极几何

目标 学习多视角几何基础学习什么是极点、极线、对极约束等 基本概念 在我们使用针孔相机时,我们会丢失大量重要的信息。比如说图像的深度,或者说图像上的点和摄像机的距离,因为这是一个从3D 到2D 的转换。因此一个重要的问题就产生了&…

[HTML]Web前端开发技术9(HTML5、CSS3、JavaScript )——喵喵画网页

希望你开心,希望你健康,希望你幸福,希望你点赞! 最后的最后,关注喵,关注喵,关注喵,佬佬会看到更多有趣的博客哦!!! 喵喵喵,你对我真的…

在线多端口排课教务管理工具:教育机构管理的得力助手

在现代教育中,教务管理是一个复杂而重要的任务。为了简化这一过程,许多在线教务管理工具应运而生。今天,我将向大家介绍一款名为乔拓云的在线多端口排课教务管理工具。 首先,乔拓云是一个功能强大的教务管理系统。它不仅提供了小程…

源码:Spring常规Bean创建过程

Bean创建过程: 一、版本 5.3.10二、学习内容 Bean创建过程源码三、Bean生命周期 时间轴地址:点击 四、bean创建过程脑图总结 脑图地址:点击 五、源码过程 说明: bean创建入口一般都是通过getBean(xxx);方法进入的&#xf…

【论文阅读】Can Large Language Models Empower Molecular Property Prediction?

文章目录 0、基本信息1、研究动机2、创新性3、方法论4、实验结果 0、基本信息 作者:Chen Qian, Huayi Tang, Zhirui Yang文章链接:Can Large Language Models Empower Molecular Property Prediction?代码链接:Can Large Language Models E…

Java项目:10 Springboot的电商书城管理系统

作者主页:源码空间codegym 简介:Java领域优质创作者、Java项目、学习资料、技术互助 文中获取源码 项目介绍 该系统分为前台展示和后台管理两大模块,前台主要是为消费者服务。该子系统实现了注册,登录,以及从浏览、下…

栈、队列专题

文章目录 栈栈的概述栈的实现栈在函数调用中的应用栈在表达式求值中的应用逆波兰表达式求值 栈在括号匹配中的应用有效的括号最长的有效括号删除字符串中的所有相邻重复项 如何获取栈内最小元素呢如何实现浏览器的前进和后退 队列队列的定义队列的实现循环队列队列的应用队列在…

解决百度地图在模拟器上运行报 java.lang.IllegalArgumentException: No config chosen问题

解决百度地图在模拟器上运行报 java.lang.IllegalArgumentException: No config chosen 问题 1. 问题复现 在近期公司使用模拟器(网易MuMu)进行项目演示时,在进入存在百度地图(Android版本 7.4.2版本)之后,页面出现奔溃,后台日志为&#xf…