五、创建型(建造者模式)
建造者模式
概念
建造者模式是一种创建型设计模式,通过使用多个简单的对象一步步构建一个复杂的对象。它将一个复杂对象的构建过程与其表示分离,从而使同样的构建过程可以创建不同的表示。
应用场景
- 复杂对象构建:当一个对象有多个属性,且这些属性的组合复杂时,例如配置文件的读取、复杂的界面元素等。
- 多个表示:需要构建的对象有不同的表示,且相同的构建过程可以生成不同的表示。
- 逐步构建:需要逐步构建对象,可能需要在不同的时间或不同的上下文中设置对象的属性。
- 不变性:当对象构建后需要保持不变的情况下,使用建造者模式可以清晰地定义对象的状态。
注意点
- 复杂性:建造者模式适用于构建复杂对象,但如果对象较简单,可能显得过于复杂。
- 灵活性:在构建对象时,如果需要频繁修改构建的顺序或逻辑,可能会导致建造者的实现复杂。
- 建造者责任:建造者的职责仅限于构建过程,避免将其他逻辑混入建造者中。
核心要素
- 产品:最终构建的复杂对象。
- 建造者接口:定义构建产品的各个部分的方法。
- 具体建造者:实现建造者接口,负责具体的构建逻辑。
- 指挥者:负责调用建造者的方法,控制构建过程。
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语句封装成一个单元,以便重用和简化数据库操作。然而,像任何编程任务一样,存储过程中的代码可能会遇到错误或异常…...

华为云AI开发平台ModelArts
华为云ModelArts:重塑AI开发流程的“智能引擎”与“创新加速器”! 在人工智能浪潮席卷全球的2025年,企业拥抱AI的意愿空前高涨,但技术门槛高、流程复杂、资源投入巨大的现实,却让许多创新构想止步于实验室。数据科学家…...

简易版抽奖活动的设计技术方案
1.前言 本技术方案旨在设计一套完整且可靠的抽奖活动逻辑,确保抽奖活动能够公平、公正、公开地进行,同时满足高并发访问、数据安全存储与高效处理等需求,为用户提供流畅的抽奖体验,助力业务顺利开展。本方案将涵盖抽奖活动的整体架构设计、核心流程逻辑、关键功能实现以及…...
DockerHub与私有镜像仓库在容器化中的应用与管理
哈喽,大家好,我是左手python! Docker Hub的应用与管理 Docker Hub的基本概念与使用方法 Docker Hub是Docker官方提供的一个公共镜像仓库,用户可以在其中找到各种操作系统、软件和应用的镜像。开发者可以通过Docker Hub轻松获取所…...
IGP(Interior Gateway Protocol,内部网关协议)
IGP(Interior Gateway Protocol,内部网关协议) 是一种用于在一个自治系统(AS)内部传递路由信息的路由协议,主要用于在一个组织或机构的内部网络中决定数据包的最佳路径。与用于自治系统之间通信的 EGP&…...
解锁数据库简洁之道:FastAPI与SQLModel实战指南
在构建现代Web应用程序时,与数据库的交互无疑是核心环节。虽然传统的数据库操作方式(如直接编写SQL语句与psycopg2交互)赋予了我们精细的控制权,但在面对日益复杂的业务逻辑和快速迭代的需求时,这种方式的开发效率和可…...

srs linux
下载编译运行 git clone https:///ossrs/srs.git ./configure --h265on make 编译完成后即可启动SRS # 启动 ./objs/srs -c conf/srs.conf # 查看日志 tail -n 30 -f ./objs/srs.log 开放端口 默认RTMP接收推流端口是1935,SRS管理页面端口是8080,可…...
大模型多显卡多服务器并行计算方法与实践指南
一、分布式训练概述 大规模语言模型的训练通常需要分布式计算技术,以解决单机资源不足的问题。分布式训练主要分为两种模式: 数据并行:将数据分片到不同设备,每个设备拥有完整的模型副本 模型并行:将模型分割到不同设备,每个设备处理部分模型计算 现代大模型训练通常结合…...
【RockeMQ】第2节|RocketMQ快速实战以及核⼼概念详解(二)
升级Dledger高可用集群 一、主从架构的不足与Dledger的定位 主从架构缺陷 数据备份依赖Slave节点,但无自动故障转移能力,Master宕机后需人工切换,期间消息可能无法读取。Slave仅存储数据,无法主动升级为Master响应请求ÿ…...

RabbitMQ入门4.1.0版本(基于java、SpringBoot操作)
RabbitMQ 一、RabbitMQ概述 RabbitMQ RabbitMQ最初由LShift和CohesiveFT于2007年开发,后来由Pivotal Software Inc.(现为VMware子公司)接管。RabbitMQ 是一个开源的消息代理和队列服务器,用 Erlang 语言编写。广泛应用于各种分布…...

R 语言科研绘图第 55 期 --- 网络图-聚类
在发表科研论文的过程中,科研绘图是必不可少的,一张好看的图形会是文章很大的加分项。 为了便于使用,本系列文章介绍的所有绘图都已收录到了 sciRplot 项目中,获取方式: R 语言科研绘图模板 --- sciRplothttps://mp.…...