09 创建型模式-建造者模式

1.建造者模式介绍:

建造者模式 (builder pattern), 也被称为生成器模式 , 是一种创建型设计模式
定义: 将一个复杂对象的构建与表示分离,使得同样的构建过程可以创建不
同的表示。

2.建造者模式要解决的问题

建造者模式可以将部件和其组装过程分开,一步一步创建一个复杂的对象。用
户只需要指定复杂对象的类型就可以得到该对象,而无须知道其内部的具体构
造细节。
在这里插入图片描述

3 建造者模式原理

在这里插入图片描述
在这里插入图片描述

3.1 建造者模式实现方式1
创建共享单车

在这里插入图片描述
在这里插入图片描述

具体产品
/*** 自行车类**/
public class Bike {private String frame; //车架private String seat; //车座public String getFrame() {return frame;}public void setFrame(String frame) {this.frame = frame;}public String getSeat() {return seat;}public void setSeat(String seat) {this.seat = seat;}
}
/*** 抽象建造者类**/
public abstract class Builder {//申明一个protect对象给子类使用protected Bike mBike = new Bike();public abstract void buildFrame();public abstract void buildSeat();public abstract Bike createBike();
}
/*** 摩拜单车建造者**/
public class MobikeBuilder extends Builder {@Overridepublic void buildFrame() {System.out.println("制作车架!");mBike.setFrame("铝合金车架");}@Overridepublic void buildSeat() {System.out.println("制作车座");mBike.setSeat("真皮车座");}@Overridepublic Bike createBike() {return mBike;}
}
/*** 哈罗单车建造者	**/
public class HelloBikeBuilder  extends Builder{@Overridepublic void buildFrame() {System.out.println("制作碳纤维车架");mBike.setFrame("碳纤维车架");}@Overridepublic void buildSeat() {System.out.println("制作橡胶车座");mBike.setFrame("橡胶车座");}@Overridepublic Bike createBike() {return mBike;}
}
指挥者类
/*** 指挥者类**/
public class Director {private Builder mBuilder;public Director(Builder mBuilder) {this.mBuilder = mBuilder;}//自行车制作方法public Bike construct(){mBuilder.buildFrame();mBuilder.buildSeat();return mBuilder.createBike();}
}
/*** 客户端**/
public class Client {public static void main(String[] args) {//1.创建指挥者Director director = new Director(new MobikeBuilder());//2.获取自行车Bike bike = director.construct();System.out.println(bike.getFrame() + "," + bike.getSeat());}}
3.2建造者模式实现方式2

在这里插入图片描述

/*** MQ连接客户端**/
public class RabbitMQClient1 {private String host = "127.0.0.1";private int port = 5672;private int mode;private String exchange;private String queue;private boolean isDurable = true;int connectionTimeout = 1000;public RabbitMQClient1(String host, int port, int mode, String exchange, String queue, boolean isDurable, int connectionTimeout) {this.host = host;this.port = port;this.mode = mode;this.exchange = exchange;this.queue = queue;this.isDurable = isDurable;this.connectionTimeout = connectionTimeout;if(mode == 1){ //工作队列模式不需要设计交换机,但是队列名称一定要有if(exchange != null){throw new RuntimeException("工作队列模式无需设计交换机");}if(queue == null || queue.trim().equals("")){throw new RuntimeException("工作队列模式名称不能为空");}if(isDurable == false){throw new RuntimeException("工作队列模式必须开启持久化");}}else if(mode == 2){ //路由模式必须设计交换机,但是不能设计队列if(exchange == null){throw new RuntimeException("路由模式下必须设置交换机");}if(queue != null){throw new RuntimeException("路由模式无须设计队列名称");}}//其他验证方式,}public void sendMessage(String msg){System.out.println("发送消息......");}public static void main(String[] args) {//每一种模式,都需要根据不同的情况进行实例化,构造方法会变得过于复杂.RabbitMQClient1 client1 = new RabbitMQClient1("192.168.52.123",5672,2,"sample-exchange",null,true,5000);client1.sendMessage("Test-MSG");}
}

在这里插入图片描述

/*** MQ连接客户端**/
public class RabbitMQClient2 {private String host = "127.0.0.1";private int port = 5672;private int mode;private String exchange;private String queue;private boolean isDurable = true;int connectionTimeout = 1000;//私有化构造方法private RabbitMQClient2() {}public String getExchange() {return exchange;}public void setExchange(String exchange) {if(mode == 1){ //工作队列模式不需要设计交换机,但是队列名称一定要有if(exchange != null){throw new RuntimeException("工作队列模式无需设计交换机");}if(queue == null || queue.trim().equals("")){throw new RuntimeException("工作队列模式名称不能为空");}if(isDurable == false){throw new RuntimeException("工作队列模式必须开启持久化");}}else if(mode == 2){ //路由模式必须设计交换机,但是不能设计队列if(exchange == null){throw new RuntimeException("路由模式下必须设置交换机");}if(queue != null){throw new RuntimeException("路由模式无须设计队列名称");}}//其他验证方式,this.exchange = exchange;}public String getHost() {return host;}public void setHost(String host) {this.host = host;}public int getPort() {return port;}public void setPort(int port) {this.port = port;}public int getMode() {return mode;}public void setMode(int mode) {if(mode == 1){ //工作队列模式不需要设计交换机,但是队列名称一定要有if(exchange != null){throw new RuntimeException("工作队列模式无需设计交换机");}if(queue == null || queue.trim().equals("")){throw new RuntimeException("工作队列模式名称不能为空");}if(isDurable == false){throw new RuntimeException("工作队列模式必须开启持久化");}}else if(mode == 2){ //路由模式必须设计交换机,但是不能设计队列if(exchange == null){throw new RuntimeException("路由模式下必须设置交换机");}if(queue != null){throw new RuntimeException("路由模式无须设计队列名称");}}this.mode = mode;}public String getQueue() {return queue;}public void setQueue(String queue) {this.queue = queue;}public boolean isDurable() {return isDurable;}public void setDurable(boolean durable) {isDurable = durable;}public int getConnectionTimeout() {return connectionTimeout;}public void setConnectionTimeout(int connectionTimeout) {this.connectionTimeout = connectionTimeout;}public void sendMessage(String msg){System.out.println("发送消息......");}/*** set方法的好处是参数的设计更加的灵活,但是通过set方式设置对象属性时,对象有可能存在中间状态(无效状态),* 并且进行属性校验时有前后顺序约束.* 破坏了不可变对象的密封性.* 怎么保证灵活设置参数又不会存在中间状态呢? 答案就是: 使用建造者模式*/public static void main(String[] args) {RabbitMQClient2 client2 = new RabbitMQClient2();client2.setHost("192.168.52.123");client2.setMode(1);client2.setQueue("queue");client2.setDurable(true);client2.sendMessage("Test-MSG2");}
}

在这里插入图片描述
4. Builder建造者类提供build()方法实现目标对象的创建

/*** 建造者模式*      1.目标类的构造方法要传入一个Builder对象*      2.builder类位于目标类的内部,并且使用static修饰*      3.builder类对象提供内置各种set方法,注意: set方法的返回值是builder本身*      4.builder类提供一个build() 方法,实现目标对象的创建**/
public class RabbitMQClient3 {//私有构造,目标类的构造方法要传入一个Builder对象private RabbitMQClient3(Builder builder){}//builder类位于目标类的内部,并且使用static修饰public static class Builder{//保证不可变对象的属性密闭性private String host = "127.0.0.1";private int port = 5672;private int mode;private String exchange;private String queue;private boolean isDurable = true;int connectionTimeout = 1000;//builder类对象提供内置各种set方法,注意: set方法的返回值是builder本身public Builder setHost(String host) {this.host = host;return this;}public Builder setPort(int port) {this.port = port;return this;}public Builder setMode(int mode) {this.mode = mode;return this;}public Builder setExchange(String exchange) {this.exchange = exchange;return this;}public Builder setQueue(String queue) {this.queue = queue;return this;}public Builder setDurable(boolean durable) {isDurable = durable;return this;}public Builder setConnectionTimeout(int connectionTimeout) {this.connectionTimeout = connectionTimeout;return this;}//builder类提供一个build() 方法,实现目标对象的创建public RabbitMQClient3 build(){if(mode == 1){ //工作队列模式不需要设计交换机,但是队列名称一定要有if(exchange != null){throw new RuntimeException("工作队列模式无需设计交换机");}if(queue == null || queue.trim().equals("")){throw new RuntimeException("工作队列模式名称不能为空");}if(isDurable == false){throw new RuntimeException("工作队列模式必须开启持久化");}}else if(mode == 2){ //路由模式必须设计交换机,但是不能设计队列if(exchange == null){throw new RuntimeException("路由模式下必须设置交换机");}if(queue != null){throw new RuntimeException("路由模式无须设计队列名称");}}return new RabbitMQClient3(this);}}public void sendMessage(String msg){System.out.println("发送消息......");}}
public class App {public static void main(String[] args) {//获取连接对象RabbitMQClient3 instance = new RabbitMQClient3.Builder().setHost("192.168.52.123").setMode(1).setPort(5672).setQueue("test").build();instance.sendMessage("test");}
}

建造者模式总结

在这里插入图片描述

建造者模式的优缺点

优点
在这里插入图片描述
在这里插入图片描述
缺点
在这里插入图片描述
在这里插入图片描述

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

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

相关文章

【Unity程序技巧】公共Update管理器

👨‍💻个人主页:元宇宙-秩沅 👨‍💻 hallo 欢迎 点赞👍 收藏⭐ 留言📝 加关注✅! 👨‍💻 本文由 秩沅 原创 👨‍💻 收录于专栏:Uni…

Spring Boot中捕获异常错误信息并将其保存到数据库中

Spring Boot中捕获异常错误信息并将其保存到数据库中: 1.创建数据库表: 首先,您需要创建一个用于存储异常信息的数据库表。可以使用SQL脚本或者使用Hibernate实体类来创建表。以下是一个用于存储异常信息的表的示例SQL: CREATE TABLE erro…

【29】c++设计模式——>策略模式

策略模式 C中的策略模式(Strategy Pattern)是一种行为型设计模式,它允许在运行时选择算法的行为。策略模式通过将算法封装成独立的类,并且使它们可以互相替换,从而使得算法的变化独立于使用算法的客户端。 策略模式通…

图像语义分割 pytorch复现DeepLab v1图像分割网络详解以及pytorch复现(骨干网络基于VGG16、ResNet50、ResNet101)

图像语义分割 pytorch复现DeepLab v1图像分割网络详解以及pytorch复现(骨干网络基于VGG16、ResNet50、ResNet101) 背景介绍2、 网络结构详解2.1 LarFOV效果分析 2.2 DeepLab v1-LargeFOV 模型架构2.3 MSc(Multi-Scale,多尺度(预测…

vim 使用文档笔记

1. i:进入编辑模式 2. ESC:进入一般命令模式 3. h 或 ←:光标向左移动一个字符 4. j 或 ↓:光标向下移动一个字符 5. k 或 ↑:光标向上移动一个字符 6. l 或 →:光标向右移动一个字符 7. num&#xf…

Matlab论文插图绘制模板第122期—函数折线图(fplot)

本期分享的是函数折线图的绘制模板。​ 所谓函数折线图,就是将自定义线函数进行可视化表达​。 先来看一下成品效果: 特别提示:本期内容『数据代码』已上传资源群中,加群的朋友请自行下载。有需要的朋友可以关注同名公号【阿昆的…

【JavaEE】网络编程---TCP数据报套接字编程

一、TCP数据报套接字编程 1.1 ServerSocket API ServerSocket 是创建TCP服务端Socket的API ServerSocket 构造方法: ServerSocket 方法: 1.2 Socket API Socket 是客户端Socket,或服务端中接收到客户端建立连接(accept方法&…

el-table表格的一些操作-表格实现单选、多选

表格实现多选 <el-table:data"dataList"borderselection-change"handleSelectionChange">//多选框<el-table-column type"selection" width"55" align"center" /></el-table> handleSelectionChange(val…

浅谈兼容性测试的关键步骤

兼容性测试是确保应用程序在多样化的技术环境中正常运行的关键步骤。它有助于提高用户满意度&#xff0c;扩大市场覆盖范围&#xff0c;同时确保法规合规性。通过正确执行兼容性测试&#xff0c;企业可以确保其应用程序在各种平台上提供一致的卓越用户体验&#xff0c;从而增强…

#电子电器架构 —— 车载网关初入门

我是穿拖鞋的汉子,魔都中坚持长期主义的汽车电子工程师。 PS:小细节,本文字数7000+,详细描述了网关在车载框架中的具体性能设置。 老规矩,分享一段喜欢的文字,避免自己成为高知识低文化的工程师: 没有人关注你。也无需有人关注你。你必须承认自己的价值,你不能站在他…

现在游戏出海有多少优势?

国内游戏市场趋于饱和&#xff0c;但是国外市场潜力仍然可观&#xff0c;因此很多人选择游戏出海&#xff0c;那么现在游戏出海有多少优势呢&#xff1f; 1、市场潜力 全球游戏市场潜力巨大&#xff0c;增长迅速。中国游戏公司具有强大的研发能力和创新能力&#xff0c;能够开…

在edge浏览器中安装好了burp的ca证书,浏览器依旧不能访问https的原因

在edge浏览器中安装好了burp的ca证书&#xff0c;浏览器依旧不能访问https的原因 1.SwitchyOmega代理插件设置2.CA证书方法1方法2 1.SwitchyOmega代理插件设置 严格安装以下图片执行&#xff0c;不可少写或多写 2.CA证书 方法1 下载好证书&#xff0c;先导入到edge浏览器的中…

人工智能和机器学习:走向智能未来的关键

人工智能&#xff08;AI&#xff09;和机器学习&#xff08;ML&#xff09;是当今IT领域中最令人振奋的发展方向之一。从自动驾驶汽车到智能助手&#xff0c;AI技术的应用正在不断扩展&#xff0c;重新定义着我们的生活方式和商业模式。在这个文章中&#xff0c;我们将深入探讨…

Qt 案例 使用QNetworkReply或者URLDownloadToFile 下载http、https资源到本地路径

Qt 使用QNetworkReply或者URLDownloadToFile两种不同方式下载http、https链接资源文件&#xff0c;并且获取下载进度。 目录 一、 使用 URLDownloadToFile 下载二、 使用 QNetworkReply 下载三、 打包好的可执行程序示例下载四、 会员或订阅专栏下载源码 一、 使用 URLDownload…

感谢我的岗位

我很高兴能够分享我干了一年嵌入式软件工程师岗位的经验。作为一名嵌入式软件工程师&#xff0c;我在这一年中积累了很多经验和技能&#xff0c;也遇到了许多挑战。在这篇文章中&#xff0c;我将分享我的经验&#xff0c;并探讨我从这个过程中学到的东西。 首先&#xff0c;我…

改变分辨率的android程序思路

在Android应用程序中&#xff0c;开发一个能够改变分辨率的功能涉及到以下几个主要步骤&#xff1a; 获取当前设备的分辨率&#xff1a;使用Android提供的DisplayMetrics类可以获取到当前设备的屏幕分辨率信息&#xff0c;包括宽度和高度。 计算新的目标分辨率&#xff1a;根据…

pv操作题目笔记

对于 pv 操作分以下几步走 什么是pv操作 PV操作在进程同步中通常指的是信号量&#xff08;Semaphore&#xff09;操作。信号量是一种用于控制多个并发进程或线程之间的同步和互斥访问的同步工具。PV操作通常涉及两个基本操作&#xff1a;P操作&#xff08;wait操作&#xff0…

hdlbits系列verilog解答(向量门操作)-14

文章目录 一、问题描述二、verilog源码三、仿真结果 一、问题描述 构建一个具有两个 3 位输入的电路&#xff0c;用于计算两个向量的按位 OR、两个向量的逻辑 OR 以及两个向量的逆 &#xff08;NOT&#xff09;。将b反相输出到out_not上半部分&#xff0c;将a 的反相输出到out…

git pull 和 git fetch 有什么区别?

一、是什么 先回顾两个命令的定义 git fetch 命令用于从另一个存储库下载对象和引用git pull 命令用于从另一个存储库或本地分支获取并集成(整合) 再来看一次git的工作流程图&#xff0c;如下所示&#xff1a; 可以看到&#xff0c;git fetch是将远程主机的最新内容拉到本地…