五、创建型(建造者模式)
建造者模式
概念
建造者模式是一种创建型设计模式,通过使用多个简单的对象一步步构建一个复杂的对象。它将一个复杂对象的构建过程与其表示分离,从而使同样的构建过程可以创建不同的表示。
应用场景
- 复杂对象构建:当一个对象有多个属性,且这些属性的组合复杂时,例如配置文件的读取、复杂的界面元素等。
- 多个表示:需要构建的对象有不同的表示,且相同的构建过程可以生成不同的表示。
- 逐步构建:需要逐步构建对象,可能需要在不同的时间或不同的上下文中设置对象的属性。
- 不变性:当对象构建后需要保持不变的情况下,使用建造者模式可以清晰地定义对象的状态。
注意点
- 复杂性:建造者模式适用于构建复杂对象,但如果对象较简单,可能显得过于复杂。
- 灵活性:在构建对象时,如果需要频繁修改构建的顺序或逻辑,可能会导致建造者的实现复杂。
- 建造者责任:建造者的职责仅限于构建过程,避免将其他逻辑混入建造者中。
核心要素
- 产品:最终构建的复杂对象。
- 建造者接口:定义构建产品的各个部分的方法。
- 具体建造者:实现建造者接口,负责具体的构建逻辑。
- 指挥者:负责调用建造者的方法,控制构建过程。
Java代码示例
// 产品
class Product {private String partA;private String partB;public void setPartA(String partA) {this.partA = partA;}public void setPartB(String partB) {this.partB = partB;}@Overridepublic String toString() {return "Product [partA=" + partA + ", partB=" + partB + "]";}
}// 建造者接口
interface Builder {void buildPartA();void buildPartB();Product getResult();
}// 具体建造者
class ConcreteBuilder implements Builder {private Product product = new Product();@Overridepublic void buildPartA() {product.setPartA("Part A");}@Overridepublic void buildPartB() {product.setPartB("Part B");}@Overridepublic Product getResult() {return product;}
}// 指挥者
class Director {private Builder builder;public Director(Builder builder) {this.builder = builder;}public void construct() {builder.buildPartA();builder.buildPartB();}
}// 客户端
public class Client {public static void main(String[] args) {Builder builder = new ConcreteBuilder();Director director = new Director(builder);director.construct();Product product = builder.getResult();System.out.println(product);}
}
各种变形用法
- 使用链式方法
可以在建造者中使用链式方法,简化代码。
// 产品
class Product {private String partA;private String partB;public void setPartA(String partA) {this.partA = partA;}public void setPartB(String partB) {this.partB = partB;}@Overridepublic String toString() {return "Product [partA=" + partA + ", partB=" + partB + "]";}
}// 建造者(链式方法)
class BuilderWithChain {private Product product = new Product();public BuilderWithChain buildPartA() {product.setPartA("Part A");return this;}public BuilderWithChain buildPartB() {product.setPartB("Part B");return this;}public Product build() {return product;}
}// 客户端
public class ClientChain {public static void main(String[] args) {BuilderWithChain builder = new BuilderWithChain();Product product = builder.buildPartA().buildPartB().build();System.out.println(product);}
}
- 复杂建造者
为不同类型的产品创建不同的建造者。
// 产品
class ComplexProduct {private String partA;private String partB;private String partC;public void setPartA(String partA) {this.partA = partA;}public void setPartB(String partB) {this.partB = partB;}public void setPartC(String partC) {this.partC = partC;}@Overridepublic String toString() {return "ComplexProduct [partA=" + partA + ", partB=" + partB + ", partC=" + partC + "]";}
}// 复杂建造者
class ComplexBuilder implements Builder {private ComplexProduct product = new ComplexProduct();@Overridepublic void buildPartA() {product.setPartA("Complex Part A");}@Overridepublic void buildPartB() {product.setPartB("Complex Part B");}public void buildPartC() {product.setPartC("Complex Part C");}@Overridepublic ComplexProduct getResult() {return product;}
}// 客户端
public class ClientComplex {public static void main(String[] args) {ComplexBuilder builder = new ComplexBuilder();builder.buildPartA();builder.buildPartB();builder.buildPartC();ComplexProduct product = builder.getResult();System.out.println(product);}
}
- 多建造者
可以同时使用多个建造者来构建产品的不同部分。
// 产品
class MultiProduct {private String partA;private String partB;public void setPartA(String partA) {this.partA = partA;}public void setPartB(String partB) {this.partB = partB;}@Overridepublic String toString() {return "MultiProduct [partA=" + partA + ", partB=" + partB + "]";}
}// 建造者接口
interface Builder {void buildPartA();void buildPartB();MultiProduct getResult();
}// 具体建造者
class BuilderA implements Builder {private MultiProduct product = new MultiProduct();@Overridepublic void buildPartA() {product.setPartA("Builder A - Part A");}@Overridepublic void buildPartB() {product.setPartB("Builder A - Part B");}@Overridepublic MultiProduct getResult() {return product;}
}class BuilderB implements Builder {private MultiProduct product = new MultiProduct();@Overridepublic void buildPartA() {product.setPartA("Builder B - Part A");}@Overridepublic void buildPartB() {product.setPartB("Builder B - Part B");}@Overridepublic MultiProduct getResult() {return product;}
}// 多建造者指挥者
class MultiBuilderDirector {private List<Builder> builders;public MultiBuilderDirector(List<Builder> builders) {this.builders = builders;}public void constructAll() {for (Builder builder : builders) {builder.buildPartA();builder.buildPartB();}}
}// 客户端
public class ClientMulti {public static void main(String[] args) {List<Builder> builders = new ArrayList<>();builders.add(new BuilderA());builders.add(new BuilderB());MultiBuilderDirector director = new MultiBuilderDirector(builders);director.constructAll();for (Builder builder : builders) {MultiProduct product = builder.getResult();System.out.println(product);}}
}
下面是几种建造者模式的变形用法的完整例子,展示了如何使用链式方法、复杂建造者和多建造者。
相关文章:
五、创建型(建造者模式)
建造者模式 概念 建造者模式是一种创建型设计模式,通过使用多个简单的对象一步步构建一个复杂的对象。它将一个复杂对象的构建过程与其表示分离,从而使同样的构建过程可以创建不同的表示。 应用场景 复杂对象构建:当一个对象有多个属性&…...
CPU超线程技术是什么,怎么启用超线程技术
超线程技术是一种允许单个物理CPU核心模拟成两个逻辑核心的技术,从而提升处理器的并行性能和效率。以下是对超线程技术的详细介绍: 基本概念:超线程(Hyper-Threading,HT)是Intel公司研发的一种技术&#x…...
vba学习系列(7)--考勤表制作
系列文章目录 文章目录 系列文章目录前言一、汇总所有工作表指定区域内容到指定工作表二、汇总所有工作表指定区域内容到指定工作表(带公式)总结 前言 一、汇总所有工作表指定区域内容到指定工作表 Sub CopyRangesToSummary()Dim sourceSheet As WorksheetDim targetSheet As…...
Java学习第九天
相同包下的类可以直接访问,不同包下的类需要导包才可以使用,导包格式:import 包名.类名 final关键字: 常量: 枚举:一种特殊的类型(反编译之后本质就是实例常量,自己定义的类,创建了几…...
【算法系列-链表】链表相交 环形链表II
【算法系列-链表】链表相交&环形链表 文章目录 【算法系列-链表】链表相交&环形链表1. 链表相交1.1 思路分析🎯1.2 解题过程🎬1.3 代码示例🌰 2. 环形链表II2.1 思路分析🎯2.2 代码示例🌰 1. 链表相交 【题目…...
使用 Go 和 Gin 框架构建简单的用户和物品管理 Web 服务
使用 Go 和 Gin 框架构建简单的用户和物品管理 Web 服务 在本项目中,我们使用 Go 语言和 Gin 框架构建了一个简单的 Web 服务,能够管理用户和物品的信息。该服务实现了两个主要接口:根据用户 ID 获取用户名称,以及根据物品 ID 获…...
【VUE】双端比较算法
假设我们有两个虚拟节点 oldVnode 和 newVnode,它们分别对应的DOM结构为: 我们需要将 oldVnode 更新为 newVnode,这时就可以使用双端比较算法了。算法本质上是将新旧节点进行一次交叉比较,尽可能地重复使用已有的节点来达到最小…...
跨界的胜利:机器学习与神经网络的物理之光
近日,2024年诺贝尔物理学奖颁发给了机器学习与神经网络领域的研究者,这是历史上首次出现这样的情况。这项奖项原本只授予对自然现象和物质的物理学研究作出重大贡献的科学家,如今却将全球范围内对机器学习和神经网络的研究和开发作为了一种能…...
容器化技术:Docker的基本概念和使用
在现代软件开发和运维中,容器化技术已经成为一种不可或缺的工具。Docker作为容器化技术的代表,以其轻量级、可移植性和隔离性等特点,赢得了广泛的关注和应用。本文将详细介绍Docker的基本概念和使用方法,帮助读者快速上手Docker容…...
EcoVadis认证内容有哪些?EcoVadis认证申请流程?
EcoVadis认证是一个国际性的可持续发展评估平台,旨在帮助全球企业和供应链评鉴其在环境、社会和治理(ESG)方面的表现。该认证框架由法国的检验、认证和检测机构必维集团(Bureau Veritas)创建,得到了众多跨国…...
Windows 搭建 Gitea
一、准备工作 1. 安装 Git:Gitea 依赖 Git 进行代码管理,所以首先需要确保系统中安装了 Git。 下载地址:https://git-scm.com/downloads/win 2. 安装数据库(可选) 默认情况下,Gitea 使用 SQLite 作为内…...
嵌入式面试——FreeRTOS篇(五) 事件标志组
本篇为:FreeRTOS事件标志组篇 1、事件标志组介绍 答: 事件标志位:用一个位,来表示事件是否发生。 事件标志组是一组事件标志位的合集,可以简单的理解事件标志组,就是一个整数。 2、事件标志组的特点 答&am…...
智能听诊器:宠物健康管理的革命
智能听诊器不仅仅是一个简单的监测工具,它代表了宠物健康管理的一次革命。通过收集和分析宠物的生理数据,智能听诊器能够帮助宠物主人和医生更好地理解宠物的健康需求,从而提供更加个性化的护理方案。 智能听诊器通过高精度的传感器…...
dfs +剪枝sudoku———poj2676
目录 前言 lowbit函数 数独 suduku 问题描述 输入 输出 问题分析 子网格位置 优化搜索顺序剪枝1 优化搜索顺序剪枝2 可行性剪枝 代码 前言 lowbit函数 这是一个利用二进制位运算取出二进制数最后一位’1‘的函数 数独 数独大家肯定都玩过,…...
机器学习:关联规则:Apriori算法、FP - Growth算法的原理、应用场景及优缺点介绍
一、关联规则算法概述 关联规则挖掘是数据挖掘中的一个重要任务,用于发现数据集中不同项之间的关联关系。 二、Apriori算法 原理 频繁项集生成:Apriori算法基于一个先验原理,即如果一个项集是频繁的,那么它的所有子集也是频繁的…...
从0开始深度学习(7)——线性回归的简洁实现
在从0开始深度学习(5)——线性回归的逐步实现中,我们手动编写了数据构造模块、损失函数模块、优化器等,但是在现代深度学习框架下,这些已经包装好了 本章展示如果利用深度学习框架简洁的实现线性回归 0 导入头文件 im…...
【网络安全 | Java代码审计】华夏ERP(jshERP)v2.3
未经许可,不得转载。 文章目录 技术框架开发环境代码审计权限校验绕过SQL注入Fastjson反序列化命令执行存储型XSS越权/未授权重置密码越权/未授权删除用户信息越权/未授权修改用户信息会话固定安全建议项目地址:https://github.com/jishenghua/jshERP 技术框架 核心框架:Sp…...
Setting the value of ‘*‘ exceeded the quota
H5之localStorage限额报错quota_exceeded the quota-CSDN博客 Uncaught DOMException: Failed to set a named property on Storage: Setting the value of background exceeded the quota. 超出了 localStorage 的最大长度。...
前端页面模块修改成可动态生成数据模块——大部分数据为GPT生成(仅供学习参考)
前端页面模块修改成可动态生成数据模块: 这些案例展示了如何通过Blade模板将前端页面模块变成可动态生成的模板。通过巧妙使用Blade语法、控制结构、CSS/JS分离、组件复用等技巧,可以大大提高代码的灵活性和复用性。在Laravel的Controller中准备好数据并…...
5.错误处理在存储过程中的重要性(5/10)
错误处理在存储过程中的重要性 引言 在数据库编程中,存储过程是一种重要的组件,它允许用户将一系列SQL语句封装成一个单元,以便重用和简化数据库操作。然而,像任何编程任务一样,存储过程中的代码可能会遇到错误或异常…...
SpringBoot-17-MyBatis动态SQL标签之常用标签
文章目录 1 代码1.1 实体User.java1.2 接口UserMapper.java1.3 映射UserMapper.xml1.3.1 标签if1.3.2 标签if和where1.3.3 标签choose和when和otherwise1.4 UserController.java2 常用动态SQL标签2.1 标签set2.1.1 UserMapper.java2.1.2 UserMapper.xml2.1.3 UserController.ja…...
centos 7 部署awstats 网站访问检测
一、基础环境准备(两种安装方式都要做) bash # 安装必要依赖 yum install -y httpd perl mod_perl perl-Time-HiRes perl-DateTime systemctl enable httpd # 设置 Apache 开机自启 systemctl start httpd # 启动 Apache二、安装 AWStats࿰…...
ffmpeg(四):滤镜命令
FFmpeg 的滤镜命令是用于音视频处理中的强大工具,可以完成剪裁、缩放、加水印、调色、合成、旋转、模糊、叠加字幕等复杂的操作。其核心语法格式一般如下: ffmpeg -i input.mp4 -vf "滤镜参数" output.mp4或者带音频滤镜: ffmpeg…...
SpringBoot+uniapp 的 Champion 俱乐部微信小程序设计与实现,论文初版实现
摘要 本论文旨在设计并实现基于 SpringBoot 和 uniapp 的 Champion 俱乐部微信小程序,以满足俱乐部线上活动推广、会员管理、社交互动等需求。通过 SpringBoot 搭建后端服务,提供稳定高效的数据处理与业务逻辑支持;利用 uniapp 实现跨平台前…...
Python爬虫(一):爬虫伪装
一、网站防爬机制概述 在当今互联网环境中,具有一定规模或盈利性质的网站几乎都实施了各种防爬措施。这些措施主要分为两大类: 身份验证机制:直接将未经授权的爬虫阻挡在外反爬技术体系:通过各种技术手段增加爬虫获取数据的难度…...
Android 之 kotlin 语言学习笔记三(Kotlin-Java 互操作)
参考官方文档:https://developer.android.google.cn/kotlin/interop?hlzh-cn 一、Java(供 Kotlin 使用) 1、不得使用硬关键字 不要使用 Kotlin 的任何硬关键字作为方法的名称 或字段。允许使用 Kotlin 的软关键字、修饰符关键字和特殊标识…...
HarmonyOS运动开发:如何用mpchart绘制运动配速图表
##鸿蒙核心技术##运动开发##Sensor Service Kit(传感器服务)# 前言 在运动类应用中,运动数据的可视化是提升用户体验的重要环节。通过直观的图表展示运动过程中的关键数据,如配速、距离、卡路里消耗等,用户可以更清晰…...
Cilium动手实验室: 精通之旅---13.Cilium LoadBalancer IPAM and L2 Service Announcement
Cilium动手实验室: 精通之旅---13.Cilium LoadBalancer IPAM and L2 Service Announcement 1. LAB环境2. L2公告策略2.1 部署Death Star2.2 访问服务2.3 部署L2公告策略2.4 服务宣告 3. 可视化 ARP 流量3.1 部署新服务3.2 准备可视化3.3 再次请求 4. 自动IPAM4.1 IPAM Pool4.2 …...
redis和redission的区别
Redis 和 Redisson 是两个密切相关但又本质不同的技术,它们扮演着完全不同的角色: Redis: 内存数据库/数据结构存储 本质: 它是一个开源的、高性能的、基于内存的 键值存储数据库。它也可以将数据持久化到磁盘。 核心功能: 提供丰…...
AD学习(3)
1 PCB封装元素组成及简单的PCB封装创建 封装的组成部分: (1)PCB焊盘:表层的铜 ,top层的铜 (2)管脚序号:用来关联原理图中的管脚的序号,原理图的序号需要和PCB封装一一…...
