设计模式:建造者模式

news/2024/5/20 17:53:12

目录

一,概念

二,不使用建造者有什么麻烦

三,格式


一,概念

建造者模式(Builder Pattern)是一种创建型设计模式,用于将复杂对象的构建与其表示分离,以便同样的构建过程可以创建不同的表示。建造者模式允许通过指定复杂对象的类型和内容逐步构造一个复杂对象,并允许它分步骤进行。

二,不使用建造者有什么麻烦

假设我们要自己开发一个Rabbitmq的客户端,在不同的工作模式下,对参数的传递有相应的要求,每一种模式都有不同的参数和参数的组合。

如果使用构造方法的方式,可以重载多种不同的参数组合,但是很难实现多种灵活组合。

如果使用set方式,这种可以达到灵活组合的目的,但是有两个问题,第一,必须提前设置mode,否则在判断的时候没办法校验。另外,set会让属性处于一个暴露的状态,而Rabbitmq客户端的性质是一个不可变对象,只要new出来之后,没必要set,set会破坏这种规则。

这个时候,建造者模式来了。

既能保证灵活组织参数,又不会让基本信息对外暴露。(属性放到内部类里面)

三,格式

1.目标类的构造方法要求传入Builder对象

2.Builder建造者位于目标类内部且用static描述

3.Builder建造者对外提供内置属性和方法,注意set返回的是Builder对象本身

4.Builder建造者提供build方法来实现对目标对象的创建

四,案例改造成建造者模式

import com.rabbitmq.client.*;import java.io.IOException;
import java.util.concurrent.TimeoutException;public class RabbitmqClient {private final ConnectionFactory factory;private Connection connection;private Channel channel;private final String exchange;private final String queue;private boolean durable;// 私有构造器,只能通过 Builder 类访问private RabbitmqClient(Builder builder) throws IOException, TimeoutException {this.factory = new ConnectionFactory();this.factory.setHost(builder.host);this.factory.setPort(builder.port);this.durable = builder.isDurable;this.exchange = builder.exchange;this.queue = builder.queue;// 创建新连接和通道this.connection = factory.newConnection();this.channel = connection.createChannel();// 声明持久的交换器channel.exchangeDeclare(exchange, "direct", durable);// 声明持久的队列,并设置排他、自动删除和绑定队列到交换器channel.queueDeclare(queue, durable, false, false, null);channel.queueBind(queue, exchange, "");}public void sendMsg(String routingKey, String msg) throws IOException {// 发送消息channel.basicPublish(exchange, routingKey, null, msg.getBytes("UTF-8"));System.out.println("Sent: " + msg);}// 资源清理public void close() throws IOException, TimeoutException {if (channel != null && channel.isOpen()) {channel.close();}if (connection != null && connection.isOpen()) {connection.close();}}// Builder 类public static class Builder {private String host = "localhost";private int port = 5672;private boolean isDurable = true;private String exchange;private String queue;public Builder setHost(String host) {this.host = host;return this;}public Builder setPort(int port) {this.port = port;return this;}public Builder setDurable(boolean durable) {isDurable = durable;return this;}public Builder setExchange(String exchange) {this.exchange = exchange;return this;}public Builder setQueue(String queue) {this.queue = queue;return this;}public RabbitmqClient build() throws IOException, TimeoutException {return new RabbitmqClient(this);}}
}// 使用示例
class Client {public static void main(String[] args) throws IOException, TimeoutException {RabbitmqClient client = new RabbitmqClient.Builder().setHost("localhost").setPort(5672).setDurable(true).setExchange("myExchange").setQueue("myQueue").build();client.sendMsg("routingKey", "Hello, RabbitMQ!");// 记得在最后关闭资源client.close();}
}

在这个示例中,RabbitmqClient 类负责创建 RabbitMQ 连接和通道,并提供了发送消息的方法 sendMsgBuilder 内部类允许用户设置连接属性,如主机、端口、交换器和队列。

客户端代码使用 Builder 类来构建 RabbitmqClient 实例,然后调用 sendMsg 方法发送消息,并在操作完成后关闭资源。

请注意,这个示例代码假设 RabbitMQ 服务器正在运行,并且客户端有权限访问指定的交换器和队列。在生产环境中,还需要考虑异常处理、连接失败重试、消息确认、事务等高级特性。


http://www.mrgr.cn/p/87855511

相关文章

go学习笔记——Kratos框架

官方文档https://go-kratos.dev/en/docs/getting-started/start/1.安装Go 参考:mac安装go1.20 2.安装Kratos框架 kratos依赖protobuf grpc等框架,需要先进行安装brew install grpc brew install protobuf brew install protoc-gen-go brew install protoc-gen-go-grpc验证pro…

js逆向,参数加密js混淆

关键词 JS 混淆、源码乱码、参数动态加密 逆向目标 题目1:抓取所有(5页)机票的价格,并计算所有机票价格的平均值,填入答案。 目标网址:https://match.yuanrenxue.cn/match/1目标接口:https://ma…

【Linux】在Linux中执行命令ifconfig, 报错-bash:ifconfig: command not found解决方案

一、报错信息 ifconfig 报错-bash:ifconfig: command not found 同时,通过ip addr查看,也看不到IP信息 二、解决方案 找到ifcfg-ens0文件,此文件的目录在/etc/sysconfig/network-scripts目录下 命令:cd /etc/sysconfig/network…

m基于遗传优化的LDPC码NMS译码算法最优归一化参数计算和误码率matlab仿真

1.算法仿真效果 matlab2022a仿真结果如下:遗传优化迭代过程:误码率对比:2.算法涉及理论知识概要低密度奇偶校验码(Low-Density Parity-Check Code, LDPC码)因其优越的纠错性能和近似香农极限的潜力,在现代通信系统中扮演着重要角色。归一化最小和(Normalized Min-Sum, NMS)…

Vue.js-----vue组件

能够说出vue生命周期能够掌握axios的使用能够了解$refs, $nextTick作用能够完成购物车案例 Vue 生命周期讲解 1.钩子函数 目标:Vue 框架内置函数,随着组件的生命周期阶段,自动执行 作用: 特定的时间点,执行特定的操作场景: 组…

交流接触器

一般按负载电流的1.5倍选择;

IPFoxy:什么是静态住宅IP?静态ISP代理指南

静态住宅代理(也称为静态ISP代理)是最流行的代理类型之一。它们也是隐藏您的身份并保持在线匿名的最佳方法之一。您为什么要使用住宅代理而不是仅使用常规代理服务?下面我具体分享。 一、什么是静态住宅代理? 首先,我…

C++学习笔记——仿函数

文章目录 仿函数——思维导图仿函数是什么仿函数的优势理解仿函数仿函数的原理举例 仿函数——思维导图 仿函数是什么 使用对象名调用operator()函数看起来像是在使用函数一样,因此便有了仿函数的称呼;仿函数存在的意义是&#x…

stm32 出现 hard fault 的排查记录

参考链接:https://blog.csdn.net/qq_43118572/article/details/1327596261、先验知识先验知识1: cortex m3 在中断/异常时,会把 8 个寄存器(xPSR、PC、LR、R12 以及R3-R0)的值压入栈。入栈顺序以及入栈后堆栈中的内容如下(CM4 是从低地址到搞地质):地址 寄存器 被保存的…

stm32 将外部 Flash挂载在 SPI 出现数据传输时好时不好的排查过程

现象: 将外部 Flash 挂载在 SPI,在 hardware_init() -> read_jedec_id() 里的 result = spi->wr(spi, cmd_data, sizeof(cmd_data), recv_data, sizeof(recv_data)) 中, recv_data 的值经常不一致,result 的值偶尔为 SFUD_SUCCESS, 大部分会 Error。备注: 正常情况…

力扣每日一题112:路径总和

题目 简单 给你二叉树的根节点 root 和一个表示目标和的整数 targetSum 。判断该树中是否存在 根节点到叶子节点 的路径,这条路径上所有节点值相加等于目标和 targetSum 。如果存在,返回 true ;否则,返回 false 。 叶子节点 是…

STM32实现1.8寸液晶屏 LCD SPI串口显示屏模块 TFT彩屏(标准库和HAL库实现)

目录 一、所选模块 液晶模块选择(淘宝上均有售卖) 模块引脚 二、嵌入式单片机型号 三、接线表设计 四、开发环境版本说明 五、标准库实现 六、HAL库实现 七、完整工程(内含标准库和HAL库源码) 代码链接 一、所选模块 液…

FFmpeg常用命令详解与实战指南

下载地址:Releases BtbN/FFmpeg-Builds (github.com) 1. 获取视频信息 使用FFmpeg获取视频信息是最基本的操作之一。你可以使用-i选项指定输入文件,然后使用FFmpeg内置的分析器来获取视频的各种信息,包括视频编解码器、音频编解码器、分辨…

【算法】滑动窗口——水果成篮

本篇博客是我对“水果成篮”这道题由暴力解法到滑动窗口思路的具体思路,有需要借鉴即可。 目录 1.题目2.暴力求解3.暴力优化3.1每次right不用回退3.2有些left长度一定不如前一个,不用走,left不回退 4.滑动窗口算法5.总结 1.题目 题目链接&am…

【win10 文件夹数量和看到不一致查看隐藏文件已经打开,Thumb文件作妖】

目录 任务介绍:重命名规则修改前修改后 实现思路VB代码实现BUG犯罪现场(眼见不一定为实)破案1:抓顶风作案的反贼!!!破案2:破隐身抓刺客!!!杀器&am…

[4]自定义Lua解析器管理器-------演化脚本V0.7

使用自定义委托通过tolua来调用多返回值和长参数类型的函数。 防踩坑指南,使用自定义委托需要将委托类型添加到CustomSettings中。[4]自定义Lua解析器管理器-------演化脚本V0.7 使用自定义委托来调用lua脚本中的多返回值函数和长参数类型的函数。 先看代码,依旧是上篇文章中…

[转帖]Mysql数据库的事务特性、隔离级别及MVCC多版本并发控制简介

https://my.oschina.net/tongchengyu/blog/4714950事务的特性 数据库如果支持事务,就要满足下面四个特性(ACID)。 原子性(A:Atomicity) 在一个事务中,多个sql操作,要么一起成功(所有数据操作都成功),要么一起回滚(其中一个没有成功,其他数据操作一起恢复到开始状态…

2010NOIP普及组真题 2. 接水问题

线上OJ: 一本通:http://ybt.ssoier.cn:8088/problem_show.php?pid1950 解法一、朴素模拟 核心思想: 朴素模拟: 1、先给每个b[i]水龙头分配一个人a[i],b[i] 表示水龙头的剩余时间。同时标记该水龙头为 used 使用中 2…