03-JAVA设计模式-建造者模式

建造者模式

什么是建造者模式

建造者模式(Builder Pattern)是一种对象构建的设计模式,它允许你通过一步一步地构建一个复杂对象,来隐藏复杂对象的创建细节。
这种模式将一个复杂对象的构建过程与其表示过程分离,使得同样的构建过程可以创建不同的表示。命名建议以Builder结尾,以达到见名之意。

在建造者模式中,通常包含以下几个角色:

  • 产品(Product):这是最终要创建的对象,它通常包含多个属性,并且可能具有复杂的内部结构。
  • 抽象建造者(Builder):这是一个接口或者抽象类,定义了创建产品所需的方法。这些方法通常是一系列设置产品属性的步骤。
  • 具体建造者(ConcreteBuilder):这个类实现了抽象建造者接口,提供了构建产品的具体实现。它包含了创建产品对象的所有逻辑,并可以一步步地设置产品对象的属性。
  • 导演者(Director):这是一个可选的角色,它负责调用建造者接口中的方法来构建产品对象。导演者可以简化客户端代码,使得客户端无需关心具体的构建步骤。

使用场景

  • 当我们要建造一个复杂的产品。比如:手机时。这种复杂产品的创建,需要处理子组件装配的问题。
  • 实际开发中,我们所需要的对象构建时也非常复杂,有很多步骤需要处理时。

建造者模式的本质

  • 分离了对象子组件的单独构造(有Buider来负责)和装配(有Director负责)。从而可以构造负责的对象。
  • 这个模式适用于在某个对象构建过程复杂的情况下使用。
  • 由于实现了构建和装配的解耦。不同的构建器,相同的装配,可以做出不同的对象; 相同的构建器,不同的装配顺序也可以做出不同的对象。也就是实现了构建算法、装配算法的解耦,实现了更好的复用。

案例

实现建造华为手机与小米手机

通过静态内部类作为建造者

Phone.java

public class Phone {// 机身private String fuselage;// 摄像头private String camera;// 系统内核private String systemKernel;// 私有构造方法,只能通过建造者创建private Phone(Builder builder) {this.fuselage = builder.fuselage;this.camera = builder.camera;this.systemKernel = builder.systemKernel;}@Overridepublic String toString() {return "Phone{" +"fuselage='" + fuselage + '\'' +", camera='" + camera + '\'' +", systemKernel='" + systemKernel + '\'' +'}';}// 静态内部类作为建造者static class Builder {// 机身private String fuselage;// 摄像头private String camera;// 系统内核private String systemKernel;public Builder setFuselage(String fuselage) {this.fuselage = fuselage;return this;    // 链式调用}public Builder setCamera(String camera) {this.camera = camera;return this;    // 链式调用}public Builder setSystemKernel(String systemKernel) {this.systemKernel = systemKernel;return this;    // 链式调用}// 创建手机public Phone createPhone(){return new Phone(this);}}
}

Client.java

public class Client {public static void main(String[] args) {Phone phone = new Phone.Builder().setCamera("华为摄像头").setFuselage("华为机身").setSystemKernel("鸿蒙系统").createPhone();System.out.println(phone);Phone phone2 = new Phone.Builder().setCamera("小米摄像头").setFuselage("小米机身").setSystemKernel("小米系统").createPhone();System.out.println(phone2);}
}

执行结果:

在这里插入图片描述

通过接口实现建造者模式

UML

在这里插入图片描述

不使用导演者

Phone.java

public class Phone {// 机身private String fuselage;// 摄像头private String camera;// 系统内核private String systemKernel;public void setFuselage(String fuselage) {this.fuselage = fuselage;}public void setCamera(String camera) {this.camera = camera;}public void setSystemKernel(String systemKernel) {this.systemKernel = systemKernel;}@Overridepublic String toString() {return "Phone{" +"fuselage=" + fuselage +", camera=" + camera +", systemKernel=" + systemKernel +'}';}
}

IPhoneBuider.java

// 手机 抽象建造者定义接口
public interface IPhoneBuider {// 设置机身IPhoneBuider setFuselage(String fuselage);// 设置摄像头IPhoneBuider setCamera(String camera);// 设置系统内核IPhoneBuider setSystemKernel(String systemKernel);// 返回创建对象Phone buildPhone();
}

PhoneBuilder.java

// 建造者具体实现
public class PhoneBuilder implements IPhoneBuider {// 定义建造者返回对象private Phone phone;public PhoneBuilder() {// 初始化Phonethis.phone = new Phone();}@Overridepublic IPhoneBuider setFuselage(String fuselage) {phone.setFuselage(fuselage);return this;}@Overridepublic IPhoneBuider setCamera(String camera) {phone.setCamera(camera);return this;}@Overridepublic IPhoneBuider setSystemKernel(String systemKernel) {phone.setSystemKernel(systemKernel);return this;}@Overridepublic Phone buildPhone() {return phone;}
}

TestClient2.java

public class TestClient2 {public static void main(String[] args) {// 创建建造具体建造者PhoneBuilder phoneBuilder = new PhoneBuilder();Phone phone = phoneBuilder.setCamera("装配小米摄像头").setFuselage("装配小米机身").setSystemKernel("装配小米系统").buildPhone();System.out.println(phone.toString());}
}

在这里插入图片描述

使用导演者

新增导演者
HuaweiDirector.java

// 华为手机导演者
public class HuaweiDirector {// 定义建造者属性private IPhoneBuider phoneBuider;public HuaweiDirector(IPhoneBuider phoneBuider) {this.phoneBuider = phoneBuider;}public Phone createPhone(){Phone phone = phoneBuider.setCamera("装配华为摄像头").setFuselage("装配华为机身").setSystemKernel("装配鸿蒙系统").buildPhone();return phone;}
}

TestClient.java

public class TestClient {public static void main(String[] args) {// 创建建造具体建造者PhoneBuilder phoneBuilder = new PhoneBuilder();// 创建导演者 传入具体建造者HuaweiDirector huaweiDirector = new HuaweiDirector(phoneBuilder);// 通过导演者构建手机Phone phone = huaweiDirector.createPhone();System.out.println(phone.toString());}
}

在这里插入图片描述

gitee源码

git clone https://gitee.com/dchh/JavaStudyWorkSpaces.git

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

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

相关文章

大语言模型上下文窗口初探(下)

由于篇幅原因,本文分为上下两篇,上篇主要讲解上下文窗口的概念、在LLM中的重要性,下篇主要讲解长文本能否成为LLM的护城河、国外大厂对长文本的态度。 3、长文本是护城河吗? 毫无疑问,Kimi从一开始就用“长文本”占领…

力扣 583. 两个字符串的删除操作

题目来源:https://leetcode.cn/problems/delete-operation-for-two-strings/description/ C题解1:动态规划 寻找word1和word2拥有的公共最长子序列,之后分别对word1和word2进行删除操作,即可使word1和word2相等。 寻找公共最长子…

【引子】C++从介绍到HelloWorld

C从介绍到HelloWorld 一、C的介绍1. 简介2. 应用场景3. C的标准![在这里插入图片描述](https://img-blog.csdnimg.cn/direct/e3efb0f207f647729b92c0b5bcd4b330.png)4. C的运行过程 二、Visual Studio的安装1. 什么是Visual Studio2. Visual Studio的安装 三、完成HelloWorld1.…

Windows系统C盘空间优化进阶:磁盘清理与Docker日志管理

Windows系统C盘空间优化进阶:磁盘清理与Docker日志管理 文章目录 Windows系统C盘空间优化进阶:磁盘清理与Docker日志管理磁盘清理工具 使用“运行”命令访问磁盘清理利用存储感知自动管理空间清理WinSxS文件夹结合手动清理策略 小结删除临时文件总结&…

2024新版PHP在线客服系统多商户AI智能在线客服系统源码机器人自动回复即时通讯聊天系统源码PC+H5

搭建环境: 服务器 CPU 2核心 ↑ 运存 2G ↑ 宽带 5M ↑ 服务器操作系统 Linux Centos7.6-7.9 ↑ 运行环境: 宝塔面板 Nginx1.18- 1.22 PHP 7.1-7.3 MYSQL 5.6 -5.7 朵米客服系统是一款全功能的客户服务解决方案,提供多渠道支持…

html5分步问卷调查表模板源码

文章目录 1.设计来源1.1 问卷调查11.2 问卷调查21.3 问卷调查31.4 问卷调查41.5 问卷调查51.6 问卷调查6 2.效果和源码2.1 完整效果2.2 源代码 源码下载 作者:xcLeigh 文章地址:https://blog.csdn.net/weixin_43151418/article/details/137454703 html5分…

simulink 的stm32 ADC模块输出在抽筋,不知为何

% outtypecast(uint16(1000),uint8) % 10003E8,E8232,out232 3 function [y,len] myfcn(u1) headuint8([255 85]);%帧头 out1typecast(uint16(u1),uint8); % out2typecast(uint16(u2),uint8); y[head,out1]; lenuint16(length(y)); 2023b版本,stm32硬件支持…

Azure runbook 使用用户托管标识查看资源状态

Azure runbook 使用用户托管标识查看资源状态 在托管标识里创建用户托管标识在被查看或变更资源进行授权创建自动化账号和runbook发布脚本添加计划 在托管标识里创建用户托管标识 在被查看或变更资源进行授权 这里是选取的Analysis Services 资源 创建自动化账号和runbook 发布…

探索K-近邻算法(KNN):原理、实践应用与文本分类实战

第一部分:引言与背景 KNN算法在机器学习领域的重要性及其地位 KNN算法作为机器学习中的基石之一,由于其概念直观、易于理解并且不需要复杂的模型训练过程,被广泛应用于多种场景。它在监督学习中占据着特殊的位置,尤其适用于实时…

【C#】读取指定XML节点

&#x1f4f0;XML文件 <?xml version"1.0" encoding"utf-8"?> <configuration><userSettings><Internal.Settings type"Desktop"><setting name"StatsDisplayCount" serializeAs"String">…

海量智库 | ANY权限原理介绍

ANY权限是Vastbase中的一种特殊的管理权限&#xff0c;用户能够通过ANY权限执行更广泛的操作&#xff0c;更加便利的管理数据库。 本文将为您介绍ANY权限管理的相关原理。 ANY权限管理相关解释 ANY权限管理&#xff0c;是对数据库内的某一类对象的所有实体进行特定的权限管理…

SQLite 4.9的 OS 接口或“VFS”(十三)

返回&#xff1a;SQLite—系列文章目录 上一篇:SQLite字节码引擎&#xff08;十二&#xff09; 下一篇:SQLite 4.9的虚拟表机制(十四) 1. 引言 本文介绍了 SQLite OS 可移植性层或“VFS” - 模块位于 SQLite 实现堆栈底部 提供跨操作系统的可移植性。 VFS是Virtual File…

TiDB 慢查询日志分析

导读 TiDB 中的慢查询日志是一项 关键的性能监控工具&#xff0c;其主要作用在于协助数据库管理员追踪执行时间较长的 SQL 查询语句。 通过记录那些超过设定阈值的查询&#xff0c;慢查询日志为性能优化提供了关键的线索&#xff0c;有助于发现潜在的性能瓶颈&#xff0c;优化…

libVLC 音频立体声模式切换

在libVLC中&#xff0c;可以使用libvlc_audio_set_channel函数来设置音频的立体声模式。这个函数允许选择不同的音频通道&#xff0c;例如立体声、左声道、右声道、环绕声等。 /*** Set current audio channel.** \param p_mi media player* \param channel the audio channel…

Java | Leetcode Java题解之第16题最接近的三数之和

题目&#xff1a; 题解&#xff1a; class Solution {public int threeSumClosest(int[] nums, int target) {Arrays.sort(nums);int n nums.length;int best 10000000;// 枚举 afor (int i 0; i < n; i) {// 保证和上一次枚举的元素不相等if (i > 0 && nums…

【精品整理】最新数据安全评估标准合集

最新数据安全评估标准合集&#xff0c;以下是资料的目录&#xff0c;共12份。如需下载&#xff0c;请前往星球查阅和获取&#xff1a;https://t.zsxq.com/18JrHhWtQ 1、网络安全标准实践指南 2、数据安全风险评估方法 3、个人信息安全影响评估指南 4、数据出境安全评估指南 5、…

HAL STM32 定时器PWM DMA输出方式

HAL STM32 定时器PWM DMA输出方式 &#x1f9e8;遗留问题&#xff1a;当配置RCR重复计数器&#xff0c;配置为2时&#xff0c;在定义了3组PWM参数情况下&#xff0c;只能输出第二组参数的PWM波形。&#xff08;HAL_TIM_PWM_Start_DMA(&htim1, TIM_CHANNEL_1, aCCValue_Buff…

模块化——如何导入模块?(内置模块与自定义模块)

在Node.js中&#xff0c;要导入另一个模块&#xff0c;我们可以使用require函数。这个函数接受一个文件路径参数&#xff0c;并返回导入的模块。 一、require使用注意事项&#xff1a; (1)自己创建的模块&#xff0c;导入时建议写相对路径&#xff0c;不能省略./和../ //我把…

golang web 开发 —— gin 框架 (gorm 链接 mysql)

目录 1. 介绍 2. 环境 3. gin 3.1 gin提供的常见路由 3.2 gin的分组 main.go router.go 代码结构 3.3 gin 提供的Json方法 main.go route.go common.go user.go order.go 3.4 gin框架下如何获取传递来的参数 第一种是GET请求后面直接 /拼上传递的参数 第二种是…

【Lavavel框架】——各目录作用的介绍

&#x1f468;‍&#x1f4bb;个人主页&#xff1a;开发者-曼亿点 &#x1f468;‍&#x1f4bb; hallo 欢迎 点赞&#x1f44d; 收藏⭐ 留言&#x1f4dd; 加关注✅! &#x1f468;‍&#x1f4bb; 本文由 曼亿点 原创 &#x1f468;‍&#x1f4bb; 收录于专栏&#xff1a…