设计模式:建造者模式教你创建复杂对象

news/2024/5/3 17:17:03/文章来源:https://blog.csdn.net/qq_24074771/article/details/128942316

一、问题场景

当我们需要创建资源池配置对象的时候,资源池配置类里面有以下成员变量:

在这里插入图片描述

如果我们使用new关键字调用构造函数,构造函数参数列表就会太长。

如果我们使用set方法设置字段值,那minIdle<=maxIdle<=maxTotal的约束逻辑就没地方写了。

二、问题分析

资源配置类,仅靠自己本身,无处安放字段属性之间的约束逻辑,仅靠本身。那就需要引入另一个类去处理检验逻辑。这就要用到这期要讲的建造者模式。

三、建造者模式定义

建造者模式将复杂对象的建造过程抽象出来,让这个抽象过程的不同实现方法可以构建出不同表现(属性)的对象。

在这里插入图片描述

(1)builder(抽象建造者):为创建一个产品对象的各个部件指定抽象接口。

(2)ConcreteBuilder(具体建造者):实现Builder的接口以构造和装配该产品的各个部件,定义并明确它所创建的表示,并提供一个检索产品的接口。

(3)Director(指挥者):构造一个使用Builder接口的对象。

(4) Product(产品角色):表示被构造的复杂对象。ConcreteBuilder创建该产品的内部表示并定义它的装配过程,包含定义组成部件的类,包括将这些部件装配成最终产品的接口。

四、建造者模式案例

//Builder角色public interface PersonBuilder {void buildHead();void buildBody();void buildFoot();Person buildPerson();}//具体建造者:ConcreteBuilderpublic class ManBuilder implements PersonBuilder {Person person;public ManBuilder() {person = new Person();}public void buildbody() {person.setBody("建造男人的身体");}public void buildFoot() {person.setFoot("建造男人的脚");}public void buildHead() {person.setHead("建造男人的头");}public Person buildPerson() {return person;}}//指挥者:Directorpublic class PersonDirector {public Person constructPerson(PersonBuilder pb) {pb.buildHead();pb.buildBody();pb.buildFoot();return pb.buildPerson();}}//产品角色:Productpublic class Person {private String head;private String body;private String foot;public String getHead() {return head;}public void setHead(String head) {this.head = head;}public String getBody() {return body;}public void setBody(String body) {this.body = body;}public String getFoot() {return foot;}public void setFoot(String foot) {this.foot = foot;}}public class Man extends Person {}//测试案例:Test
public class Test{
public static void main(String[] args) {
PersonDirector pd = new PersonDirector();
Person person = pd.constructPerson(new ManBuilder());
System.out.println(person.getBody());
System.out.println(person.getFoot());
System.out.println(person.getHead());
}
}//结果:result
建造男人的身体
建造男人的脚
建造男人的头

如果系统中只需要一个具体建造者的话,可以省略掉抽象建造者和指导者,让Buider自己扮演指导者和建造者双重角色。

五、建造者模式应用

1、java. lang. StringBuilder中的建造者模式

源码中建造者模式角色分析

(1)Appendable 接口定义了多个append方法(抽象方法), 即Appendable 为抽象建造者, 定义了抽象方法

(2)AbstractStringBuilder 实现了 Appendable接口方法,这里的 AbstractStringBuilder已经是建造者,只是不能实例化

(3)StringBuilder 即充当了指挥者角色,同时充当了具体的建造者,建造方法的实现是由 AbstractStringBuilder完成, 而StringBuilder 继承了AbstractStringBuilder

2、myBatis里SqlSessionFactoryBuilder和xmlConfigBuilder也采用了建造者模式

六、建造者模式适用场景

1、对象结构复杂 : 对象有非常复杂的内部结构 , 有很多属性

2、构建不同属性对象:构建同类型但属性不同的对象

3、分离创建和使用 : 想把复杂对象的创建和使用分离

七、建造者模式和工程模式区别

工厂模式是用来创建不同但是相关类型的对象(继承同一父类或者接口的一组子类),由给定的参数来决定创建哪种类型的对象。

建造者模式是用来创建一种类型的复杂对象,可以通过设置不同的可选参数,定制化地创建不同的对象。

八、问题实现

建造者模式已经讲解清楚,那开篇提到的资源池配置对象用建造者模式怎么设计实现呢?你自己可以先试试实现一下,下期文章揭晓答案。

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

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

相关文章

数据分析实战项目3:RFM用户分群

目录1、RFM模型介绍2、Excel实际RFM划分案例3、RFM案例3.1 数据加载和基本信息查看3.2 数据预处理和RFM的初始值计算3.3 RFM区间和划分和分值计算3.4 RFM计算结果保存3.4.1 保存到excel3.4.2 保存到数据库3.5 RFM计算结果可视化3.6 结果分析&#xff08;营销建议&#xff09;3.…

干货|PCB板上的丝印位号与极性符号的组装性设计

PCB板上的字符很多&#xff0c;那么字符在后期起着那些非常重要的作用呢&#xff1f;一般常见的字符:“R”代表着电阻&#xff0c;"C”代表着电容&#xff0c;“RV”表示的是可调电阻&#xff0c;“L”表示的是电感&#xff0c;“Q”表示的是三极管&#xff0c;“D”表示的…

Linux系列文章 —— 进程概念(图解PCB、进程的描述、状态、创建、组织、查看详解)

系列文章目录 文章目录系列文章目录前言一、冯诺依曼体系结构二、操作系统三、进程概念进程概念描述进程&#xff08;PCB&#xff09;组织进程查看进程创建进程&#xff08;fork&#xff09;进程队列进程状态运行状态 - R睡眠状态 - S停止状态 - T僵尸进程 - Z孤儿进程进程优先…

Tomcat构建高负载WEB服务器(一)

前言Tomcat部署Tomcat多实例 1.前言 1.1什么是JAVA虚拟机 所谓虚拟机&#xff0c;就是一台虚拟的计算机。他是一款软件&#xff0c;用来执行一系列虚拟计算机指令。大体上&#xff0c;虚拟机可以分为系统虚拟机和程序虚拟机。大名鼎鼎的VisualBox、VMware就属于系统虚拟机。他们…

Vue - 驼峰和短横线分割命名注意事项

Vue - 驼峰和短横线分割命名注意事项一. 驼峰和短横线分割命名注意事项1.1 组件注册命名1.2 父子组件数据传递时命名1.3 父子组件函数传递一. 驼峰和短横线分割命名注意事项 我们一般定义组件的方式有两种&#xff1a; 短横线分隔命名&#xff1a;kebab-case。首字母大写命名…

PyQt5常用控件大全(详尽方法 + 实例操作,持续更新中…)

1. Label&#xff1a;标签控件 1.1 简介 标签控件主要用于显示用户不能编辑的文本&#xff0c;标识窗体上的对象&#xff08;例如&#xff1a;给文本框、列表框添加&#xff0c;描述信息等&#xff09;。它对应PyQt5中的QLabel类&#xff0c;Label控件在本质上是QLabel类的一个…

进阶技术:Linux Arm32是如何调用C Main的

前言&#xff1a; Linux x64通过qemu的rdinit方式调用的C Main&#xff0c;实际上是通过load_elf_binary(加载和解析elf)和start_thread(设置Ip和sp)&#xff0c;用缺页异常来调用。关于这点可以看这篇文章&#xff1a;点击查看。那么Arm32里面是如何调用C Main的呢&#xff1f…

BGP 属性分类及路由优先级选择

BGP 属性分类及路由优先级选择一、常见BGP属性类型1、公认必遵属性&#xff08;所有BGP路由器必须遵守的原则&#xff09;2、公认可遵属性&#xff08;所有路由器都能识别但不一定遵守&#xff09;3、可选传递属性&#xff08;不是所有BGP路由器都能识别&#xff0c;但是所有BG…

Dubbo3简单使用

Dubbo3简单使用 &#x1f449; 使用Spring Boot实现Dubbo3&#xff0c;请参见以下地址。 # Dubbo3官网地址 https://cn.dubbo.apache.org/zh/# 使用SpringBoot实现Dubbo3的地址 https://cn.dubbo.apache.org/zh/docs3-v2/java-sdk/quick-start/spring-boot/# 该项目的git地址…

【Spark分布式内存计算框架——Spark Core】3. RDD 创建、RDD函数(上)

2.4 RDD 分区数目 在讲解 RDD 属性时&#xff0c;多次提到了分区&#xff08;partition&#xff09;的概念。分区是一个偏物理层的概念&#xff0c;也是 RDD 并行计算的核心。数据在 RDD 内部被切分为多个子集合&#xff0c;每个子集合可以被认为是一个分区&#xff0c;运算逻…

ChatGPT使用

ChatGPT使用1使用全局模式2无痕模式3日期4短信平台5注册6使用ChatGPT1使用全局模式 因为后面注册时候的号码是印度尼西亚&#xff0c;所以这里我也选择印度尼西亚。 2无痕模式 打开浏览器无痕模式 由于后面网易都是英文&#xff0c;可以在无痕模式里面使用插件 3日期…

mycat学习

安装部署下载1&#xff1a;mycat2-install-template-1.21.zip下载2&#xff1a;mycat2-1.21-release-jar-with-dependencies.jar解压mycat2-install-template-1.21.zipunzip mycat2-install-template-1.21.zip把mycat2-1.21-release-jar-with-dependencies.jar放在mycat/lib中修…

Python列表的元素比较

在用python处理多个列表元素时&#xff0c;需要处理的信息一般比较多且杂。这时运用Python列表元素比较的方法&#xff0c;就能快速处理列表信息&#xff0c;能更轻松访问每个元素。1 问题如何运用Python列表的元素比较解决问题。2 方法方法一 for循环&#xff0c;此情况是list…

车道线检测-Eigenlanes 论文学习笔记

论文&#xff1a;《Eigenlanes: Data-Driven Lane Descriptors for Structurally Diverse Lanes》 代码&#xff1a;https://github.com/dongkwonjin/Eigenlanes 核心&#xff1a;在 Eigenlane Space 中检测车道线 创新点 Eigenlane&#xff1a;数据驱动的车道描述符&#xff…

VHDL语言基础-组合逻辑电路-基本逻辑门电路

数字电路中的四种基本操作是与、或、非及触发器操作&#xff0c;前三种为组合电路&#xff0c;后一种为时序电路。与非 、或非和异或的操作仍然是与、或、非的基本操作。与、或、非、与非、或非和异或等基本逻辑门电路为常用的门电路。 二输入与非门是一种常用的简单逻辑电路&a…

RabbitMQ 部署指南

RabbitMQ 部署指南RabbitMQ部署指南1.单机部署1.1.下载镜像1.2.安装MQ2.安装DelayExchange插件2.1.下载插件2.2.上传插件2.3.安装插件3.集群部署2.1.集群分类2.2.获取cookie2.3.准备集群配置2.4.启动集群2.5.测试2.5.1.数据共享测试2.5.2.可用性测试4.镜像模式4.1.镜像模式的特…

ant-design V4升级V5记录(成功篇)

官方文档&#xff1a;https://ant.design/docs/react/migration-v5-cn 1、安装运行工具之前&#xff0c;提交本地修改内容&#xff1b; 2、工具运行完&#xff0c;根据提示修改文件问题&#xff1b; 3、移除config文件中module&#xff0c; [import,{libraryName:antd, libr…

OpenResty(5):Openresty 模板渲染

1 导入lua-resty-template 下载 http://luarocks.org/modules/bungle/lua-resty-template 将template.lua文件复制到openresty/lualib/resty/目录下 2 示例 2.1 修改nginx.conf 设置模板路径&#xff1a;set $template_root /usr/local/openresty/nginx/html/templates; 设…

windows 重启redis的方法

目录打开本地的文件夹选中文件的路径输入cmd在cmd命令窗口中输入以下的指令指令的内容以及对应的命令含义前言&#xff1a;最近在本地搭建redis环境&#xff0c;突然发现本地的redis启动失败了&#xff0c;使用reids的启动命令也不行&#xff0c;于是找了不少的方法&#xff0c…

六、Linux文件 - lseek函数

目录 1.lseek函数 2.lseek函数实战 2.1宏SEEK_CUR的用法 2.2宏SEEK_END的用法 3.Open函数实战 - O_APPEND的用法 4.Linux在库函数中寻找相应的宏定义 1.lseek函数 off_t lseek(int fd,off_t offset,int whence);光标的偏移量 fd:文件描述符offset:偏移量whence: SEEK_…