[设计模式Java实现附plantuml源码~创建型] 复杂对象的组装与创建——建造者模式
前言:
为什么之前写过Golang 版的设计模式,还在重新写Java版?
答:因为对于我而言,当然也希望对正在学习的大伙有帮助。Java作为一门纯面向对象的语言,更适合用于学习设计模式。
为什么类图要附上uml
因为很多人学习有做笔记的习惯,如果单纯的只是放一张图片,那么学习者也只能复制一张图片,可复用性较低,附上uml,方便有新理解时,快速出新图。
🔥[设计模式Java实现附plantuml源码]专链
- 确保对象的唯一性~单例模式
- 集中式工厂的实现~简单工厂模式
- 多态工厂的实现——工厂方法模式
- 产品族的创建——抽象工厂模式
- 对象的克隆~原型模式
- 复杂对象的组装与创建——建造者模式
文章目录
- 复杂对象的组装与创建——建造者模式
- 代码简单实现
- 建造者模式总结
- 建造者模式的主要优点如下:
- 建造者模式的主要缺点如下:
- 适用场景
复杂对象的组装与创建——建造者模式
建造者模式(Builder Pattern):将一个复杂对象的构建与它的表示分离,使得同样的构建过程可以创建不同的表示。
建造者模式是一种对象创建型模式。建造者模式一步一步地创建一个复杂的对象,它允许用户只通过指定复杂对象的类型和内容就可以构建它们,用户不需要知道内部的具体构建细节。

@startumlclass Product {- partA- partB- partC}abstract class Builder {+ buildPartA()+ buildPartB()+ buildPartC()+ getResult(): Product
}class Director {
- builder
+ construct()
}
note left of Director::"construct()"builder.buildPartA();builder.buildPartB();builder.buildPartC()return builder.getResult();
end noteDirector *-> Builder: 指挥者跟builder属于组合关系class concreteBuilder extends Builder {+ buildPartA()+ buildPartB()+ buildPartC()+ getResult(): Product
}concreteBuilder .left..> Product : 具体建造者生产对象@enduml
在建造者模式结构中包含以下4个角色。
(1)Builder(抽象建造者):它为创建一个产品Product对象的各个部件指定抽象接口。在该接口中一般声明两类方法:一类方法是 buildPartX(),用于创建复杂对象的各个部件;另一类方法是 getResult(),用于返回复杂对象。Builder既可以是抽象类,也可以是接口。
(2)ConcreteBuilder(具体建造者):它实现了Builder接口,实现各个部件的具体构造和装配方法,定义并明确其所创建的复杂对象,也可以提供一个方法返回创建好的复杂产品对象。
(3)Product(产品角色):它是被构建的复杂对象,包含多个组成部件。具体建造者创建该产品的内部表示并定义其装配过程。
(4)Director(指挥者):指挥者又称为导演类,它负责安排复杂对象的建造次序。指挥者与抽象建造者之间存在关联关系,可以在其 construct() 建造方法中调用建造者对象的部件构造与装配方法,完成复杂对象的建造。客户端一般只需要与指挥者进行交互,在客户端确定具体建造者的类型,并实例化具体建造者对象(也可以通过配置文件和反射机制),然后通过指挥者类的构造函数或者Setter方法将该对象传入指挥者类中。
代码简单实现
package create;// 使用示例
public class BuilderDemo {public static void main(String[] args) {Car car = new CarBuilder().setBrand("Toyota").setModel("Camry").setYear(2022).setHorsepower(203).build();System.out.println(car);}
}// 产品类
class Car {private final String brand;private final String model;private final int year;private final int horsepower;public Car(String brand, String model, int year, int horsepower) {this.brand = brand;this.model = model;this.year = year;this.horsepower = horsepower;}// Getters// ...@Overridepublic String toString() {return "Car [brand=" + brand + ", model=" + model + ", year=" + year + ", horsepower=" + horsepower + "]";}
}// 建造者类
class CarBuilder {private String brand;private String model;private Integer year;private Integer horsepower;public CarBuilder setBrand(String brand) {this.brand = brand;return this;}public CarBuilder setModel(String model) {this.model = model;return this;}public CarBuilder setYear(int year) {this.year = year;return this;}public CarBuilder setHorsepower(int horsepower) {this.horsepower = horsepower;return this;}public Car build() {if (brand == null || model == null || year == null || horsepower == null) {throw new RuntimeException("没有完全建造产品");}return new Car(brand, model, year, horsepower);}
}
建造者模式总结
建造者模式的主要优点如下:
(1)在建造者模式中,客户端不必知道产品内部组成的细节,将产品本身与产品的创建过程解耦,使得相同的创建过程可以创建不同的产品对象。
(2)每个具体建造者都相对独立,而与其他具体建造者无关。因此,可以很方便地替换具体建造者或增加新的具体建造者,用户使用不同的具体建造者即可得到不同的产品对象。由于指挥者类针对抽象建造者编程,增加新的具体建造者无须修改原有类库的代码,系统扩展方便,符合开闭原则。
(3)可以更加精细地控制产品的创建过程。将复杂产品的创建步骤分解在不同的方法中,使得创建过程更加清晰,也更方便使用程序来控制创建过程。
建造者模式的主要缺点如下:
(1)建造者模式所创建的产品一般具有较多的共同点,其组成部分相似。如果产品之间的差异性很大,例如很多组成部分都不相同,就不适合使用建造者模式,因此其使用范围受到一定的限制。
(2)如果产品的内部结构复杂且多变,可能会需要定义很多具体建造者类来实现这种变化,这就导致系统变得很庞大,增加系统的理解难度和运行成本。
适用场景
在以下情况下可以考虑使用建造者模式:
(1)需要生成的产品对象有复杂的内部结构,这些产品对象通常包含多个成员变量。
(2)需要生成的产品对象的属性相互依赖,需要指定其生成顺序。
(3)对象的创建过程独立于创建该对象的类。在建造者模式中通过引入指挥者类,将创建过程封装在指挥者类中,而不在建造者类和客户类中。
(4)隔离复杂对象的创建和使用,并使得相同的创建过程可以创建不同的产品。
🚀 作者简介:作为某云服务提供商的后端开发人员,我将在这里与大家简要分享一些实用的开发小技巧。在我的职业生涯中积累了丰富的经验,希望能通过这个博客与大家交流、学习和成长。技术栈:Java、PHP、Python、Vue、React
本文收录于三木的
💐 「设计模式」专栏
此外三木还有以下专栏在同步更新~
🌼 「AI」专栏
🔥「面试」这个专栏的灵感来自于许多粉丝私信,大家向我咨询有关面试的问题和建议。我深感荣幸和责任,希望通过这个专栏,能够为大家提供更多关于面试的知识、技巧和经验。我们将一起探讨面试。期待粉丝们ssp的offer喜讯。
🎈 「Java探索者之路」系列专栏,这个专栏旨在引领Java开发者踏上一段真正探索Java世界的旅程。
我们将深入探讨Java编程的方方面面,从基础知识到高级技巧,从实践案例到最新趋势,帮助你成为一名卓越的Java探索者。如果有想进入Java后端领域工作的同学,这个专栏会对你有所帮助,欢迎关注起来呀
🌊 「Python爬虫」的入门学习系列,大家有兴趣的可以看一看
🌹一起学习,互三互访,顺评论区有访必回,有关必回!!!
相关文章:
[设计模式Java实现附plantuml源码~创建型] 复杂对象的组装与创建——建造者模式
前言: 为什么之前写过Golang 版的设计模式,还在重新写Java 版? 答:因为对于我而言,当然也希望对正在学习的大伙有帮助。Java作为一门纯面向对象的语言,更适合用于学习设计模式。 为什么类图要附上uml 因为很…...
【国产MCU】-认识CH32V307及开发环境搭建
认识CH32V307及开发环境搭建 文章目录 认识CH32V307及开发环境搭建1、CH32V307介绍2、开发环境搭建3、程序固件下载1、CH32V307介绍 CH32V307是沁恒推出的一款基于32位RISC-V设计的互联型微控制器,配备了硬件堆栈区、快速中断入口,在标准RISC-V基础上大大提高了中断响应速度…...
python flask request教程
request 一、传json1、resquest.get_data()与resquest.data2、request.get_json()3、request.json["imageURL"]二、传file1、request.files["file"]2、request.form["username"]3、request.form.get(username)与2等价,其他get()与[]也相同三、其…...
UE5 Chaos系统 学习笔记
记得开插件: 1、锚点场(构造场) 在锚点场范围内的物体静止且不被其他力场损坏 需要在Geometry Collection的初始化场把构造场设置过去 2、ClusterStrain 破裂效果的力 3、DisableField chaos破裂后的模拟物理在绿色范围内禁止行为和模拟物…...
MkDocs 部署指南
简介 MkDocs 可以同时编译多个 markdown 文件,形成书籍一样的文件。有多种主题供你选择,很适合项目使用。 MkDocs 是快速,简单和华丽的静态网站生成器,可以构建项目文档。文档源文件在 Markdown 编写,使用单个 YAML …...
【Java 设计模式】行为型之访问者模式
文章目录 1. 定义2. 应用场景3. 代码实现结语 访问者模式(Visitor Pattern)是一种行为型设计模式,用于在不改变被访问元素的类的前提下定义对这些元素的新操作。访问者模式将数据结构与作用于结构上的操作解耦,使得操作集合可以灵…...
堆和堆排序【数据结构】
目录 一、堆1. 堆的存储定义2. 初始化堆3. 销毁堆4. 堆的插入向上调整算法 5. 堆的删除向下调整算法 6. 获取堆顶数据7. 获取堆的数据个数8. 堆的判空 二、Gif演示三、 堆排序1. 堆排序(1) 建大堆(2) 排序 2.Topk问题 四、完整代码1.堆的代码Heap.cHeap.htest.c 2. 堆排序的代码…...
【全程录屏GPT3.5升级4.0】2024最新GPT4升级订阅详细指南
前言:为什么要升级GPT4.0,下图是来自GPT4.0的官方回答,可以看出,GPT4无愧于是一个大版本升级的。 一、视频教程 记录了普通用户使用WildCrad从GPT3.5升级到4.0的全部过程,感兴趣可以前往观看:https://www.…...
中移(苏州)软件技术有限公司面试问题与解答(4)—— virtio所创建的设备1
接前一篇文章:中移(苏州)软件技术有限公司面试问题与解答(0)—— 面试感悟与问题记录 本文参考以下文章: VirtIO实现原理——PCI基础 VirtIO实现原理——virtblk设备初始化 特此致谢! 本文对…...
《动手学深度学习(PyTorch版)》笔记5
注:书中对代码的讲解并不详细,本文对很多细节做了详细注释。另外,书上的源代码是在Jupyter Notebook上运行的,较为分散,本文将代码集中起来,并加以完善,全部用vscode在python 3.9.18下测试通过,…...
QT中wchar_t类型如何输出
在Qt中,通常使用QString来处理字符串,而不是wchar_t。QString是Qt中用于处理Unicode字符串的类。如果你有wchar_t类型的字符串,你可以将其转换为QString进行输出。 以下是一个简单的例子: #include <QCoreApplication> #i…...
网络安全04-sql注入靶场第一关
目录 一、环境准备 1.1我们进入第一关也如图: 编辑 二、正式开始第一关讲述 2.1很明显它让我们在标签上输入一个ID,那我们就输入在链接后面加?id1 编辑 2.2链接后面加个单引号()查看返回的内容,127.0.0.1/sqli/less-1/?id1,id1 …...
微服务理解篇
一 :架构演变 1 单体架构: 简单理解为一个服务涵盖所有需求功能2 垂直架构: 按照业务功能将单体架构拆分成小模块服务, 如:订单系统,用户系统,商品系统 ##缺点 引入分布式事务,分布式锁等,优点:模块解耦## 垂直拆分:根据业务层级拆分,比如商城的订单系统,用户系统,商品系统…...
项目篇:基于TCP通信模型的外卖软件实现
一、基本成员及功能实现 本项目主要由服务器,消费者,商家,外卖员组成。基本的功能如下。 对所有人: 1、可以注册登录 2、可以修改个人信息 3、可以销户 商家: 1、注册时需要填写售卖商品信息 2、可以修改商品信…...
深入浅出 diffusion(2):pytorch 实现 diffusion 加噪过程
我在上篇博客深入浅出 diffusion(1):白话 diffusion 原理(无公式)中介绍了 diffusion 的一些基本原理,其中谈到了 diffusion 的加噪过程,本文用pytorch 实现下到底是怎么加噪的。 import torch…...
【软件测试】学习笔记-构建并执行 JMeter 脚本的正确姿势
有些团队在组建之初往往并没有配置性能测试人员,后来随着公司业务体量的上升,开始有了性能测试的需求,很多公司为了节约成本会在业务测试团队里选一些技术能力不错的同学进行性能测试,但这些同学也是摸着石头过河。他们会去网上寻…...
iOS 面试 Swift基础题
一、Swift 存储属性和计算属性比较: 存储型属性:用于存储一个常量或者变量 计算型属性: 计算性属性不直接存储值,而是用 get / set 来取值 和 赋值,可以操作其他属性的变化. 计算属性可以用于类、结构体和枚举,存储属性只能用于类和结构体。存储属性可…...
(七)for循环控制
文章目录 用法while的用法for的用法两者之间的联系可以相互等价用for改写while示例for和while的死循环怎么写for循环见怪不怪表达式1省略第一.三个表达式省略(for 改 while)全省略即死循环(上面已介绍) 用法 类比学习while语句 …...
ASP .NET Core Api 使用过滤器
过滤器说明 过滤器与中间件很相似,过滤器(Filters)可在管道(pipeline)特定阶段(particular stage)前后执行操作。可以将过滤器视为拦截器(interceptors)。 过滤器级别范围…...
CodeGPT--(Visual )
GitCode - 开发者的代码家园 gitcode.com/ inscode.csdn.net/liujiaping/java_1706242128563/edit?openFileMain.java&editTypelite marketplace.visualstudio.com/items?itemNameCSDN.csdn-codegpt&spm1018.2226.3001.9836&extra%5Butm_source%5Dvip_chatgpt_c…...
深入浅出Asp.Net Core MVC应用开发系列-AspNetCore中的日志记录
ASP.NET Core 是一个跨平台的开源框架,用于在 Windows、macOS 或 Linux 上生成基于云的新式 Web 应用。 ASP.NET Core 中的日志记录 .NET 通过 ILogger API 支持高性能结构化日志记录,以帮助监视应用程序行为和诊断问题。 可以通过配置不同的记录提供程…...
Unity3D中Gfx.WaitForPresent优化方案
前言 在Unity中,Gfx.WaitForPresent占用CPU过高通常表示主线程在等待GPU完成渲染(即CPU被阻塞),这表明存在GPU瓶颈或垂直同步/帧率设置问题。以下是系统的优化方案: 对惹,这里有一个游戏开发交流小组&…...
uni-app学习笔记二十二---使用vite.config.js全局导入常用依赖
在前面的练习中,每个页面需要使用ref,onShow等生命周期钩子函数时都需要像下面这样导入 import {onMounted, ref} from "vue" 如果不想每个页面都导入,需要使用node.js命令npm安装unplugin-auto-import npm install unplugin-au…...
前端导出带有合并单元格的列表
// 导出async function exportExcel(fileName "共识调整.xlsx") {// 所有数据const exportData await getAllMainData();// 表头内容let fitstTitleList [];const secondTitleList [];allColumns.value.forEach(column > {if (!column.children) {fitstTitleL…...
大语言模型如何处理长文本?常用文本分割技术详解
为什么需要文本分割? 引言:为什么需要文本分割?一、基础文本分割方法1. 按段落分割(Paragraph Splitting)2. 按句子分割(Sentence Splitting)二、高级文本分割策略3. 重叠分割(Sliding Window)4. 递归分割(Recursive Splitting)三、生产级工具推荐5. 使用LangChain的…...
Java多线程实现之Callable接口深度解析
Java多线程实现之Callable接口深度解析 一、Callable接口概述1.1 接口定义1.2 与Runnable接口的对比1.3 Future接口与FutureTask类 二、Callable接口的基本使用方法2.1 传统方式实现Callable接口2.2 使用Lambda表达式简化Callable实现2.3 使用FutureTask类执行Callable任务 三、…...
【论文笔记】若干矿井粉尘检测算法概述
总的来说,传统机器学习、传统机器学习与深度学习的结合、LSTM等算法所需要的数据集来源于矿井传感器测量的粉尘浓度,通过建立回归模型来预测未来矿井的粉尘浓度。传统机器学习算法性能易受数据中极端值的影响。YOLO等计算机视觉算法所需要的数据集来源于…...
[10-3]软件I2C读写MPU6050 江协科技学习笔记(16个知识点)
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16...
反射获取方法和属性
Java反射获取方法 在Java中,反射(Reflection)是一种强大的机制,允许程序在运行时访问和操作类的内部属性和方法。通过反射,可以动态地创建对象、调用方法、改变属性值,这在很多Java框架中如Spring和Hiberna…...
初学 pytest 记录
安装 pip install pytest用例可以是函数也可以是类中的方法 def test_func():print()class TestAdd: # def __init__(self): 在 pytest 中不可以使用__init__方法 # self.cc 12345 pytest.mark.api def test_str(self):res add(1, 2)assert res 12def test_int(self):r…...
