当前位置: 首页 > news >正文

五、创建型(建造者模式)

建造者模式

概念
建造者模式是一种创建型设计模式,通过使用多个简单的对象一步步构建一个复杂的对象。它将一个复杂对象的构建过程与其表示分离,从而使同样的构建过程可以创建不同的表示。


应用场景

  1. 复杂对象构建:当一个对象有多个属性,且这些属性的组合复杂时,例如配置文件的读取、复杂的界面元素等。
  2. 多个表示:需要构建的对象有不同的表示,且相同的构建过程可以生成不同的表示。
  3. 逐步构建:需要逐步构建对象,可能需要在不同的时间或不同的上下文中设置对象的属性。
  4. 不变性:当对象构建后需要保持不变的情况下,使用建造者模式可以清晰地定义对象的状态。

注意点

  • 复杂性:建造者模式适用于构建复杂对象,但如果对象较简单,可能显得过于复杂。
  • 灵活性:在构建对象时,如果需要频繁修改构建的顺序或逻辑,可能会导致建造者的实现复杂。
  • 建造者责任:建造者的职责仅限于构建过程,避免将其他逻辑混入建造者中。

核心要素

  1. 产品:最终构建的复杂对象。
  2. 建造者接口:定义构建产品的各个部分的方法。
  3. 具体建造者:实现建造者接口,负责具体的构建逻辑。
  4. 指挥者:负责调用建造者的方法,控制构建过程。

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);}
}

各种变形用法

  1. 使用链式方法
    可以在建造者中使用链式方法,简化代码。
// 产品
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);}
}
  1. 复杂建造者
    为不同类型的产品创建不同的建造者。
// 产品
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);}
}
  1. 多建造者
    可以同时使用多个建造者来构建产品的不同部分。
// 产品
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);}}
}

下面是几种建造者模式的变形用法的完整例子,展示了如何使用链式方法、复杂建造者和多建造者。

相关文章:

五、创建型(建造者模式)

建造者模式 概念 建造者模式是一种创建型设计模式&#xff0c;通过使用多个简单的对象一步步构建一个复杂的对象。它将一个复杂对象的构建过程与其表示分离&#xff0c;从而使同样的构建过程可以创建不同的表示。 应用场景 复杂对象构建&#xff1a;当一个对象有多个属性&…...

CPU超线程技术是什么,怎么启用超线程技术

超线程技术是一种允许单个物理CPU核心模拟成两个逻辑核心的技术&#xff0c;从而提升处理器的并行性能和效率。以下是对超线程技术的详细介绍&#xff1a; 基本概念&#xff1a;超线程&#xff08;Hyper-Threading&#xff0c;HT&#xff09;是Intel公司研发的一种技术&#x…...

vba学习系列(7)--考勤表制作

系列文章目录 文章目录 系列文章目录前言一、汇总所有工作表指定区域内容到指定工作表二、汇总所有工作表指定区域内容到指定工作表(带公式)总结 前言 一、汇总所有工作表指定区域内容到指定工作表 Sub CopyRangesToSummary()Dim sourceSheet As WorksheetDim targetSheet As…...

Java学习第九天

相同包下的类可以直接访问&#xff0c;不同包下的类需要导包才可以使用&#xff0c;导包格式&#xff1a;import 包名.类名 final关键字&#xff1a; 常量&#xff1a; 枚举&#xff1a;一种特殊的类型(反编译之后本质就是实例常量&#xff0c;自己定义的类&#xff0c;创建了几…...

【算法系列-链表】链表相交 环形链表II

【算法系列-链表】链表相交&环形链表 文章目录 【算法系列-链表】链表相交&环形链表1. 链表相交1.1 思路分析&#x1f3af;1.2 解题过程&#x1f3ac;1.3 代码示例&#x1f330; 2. 环形链表II2.1 思路分析&#x1f3af;2.2 代码示例&#x1f330; 1. 链表相交 【题目…...

使用 Go 和 Gin 框架构建简单的用户和物品管理 Web 服务

使用 Go 和 Gin 框架构建简单的用户和物品管理 Web 服务 在本项目中&#xff0c;我们使用 Go 语言和 Gin 框架构建了一个简单的 Web 服务&#xff0c;能够管理用户和物品的信息。该服务实现了两个主要接口&#xff1a;根据用户 ID 获取用户名称&#xff0c;以及根据物品 ID 获…...

【VUE】双端比较算法

假设我们有两个虚拟节点 oldVnode 和 newVnode&#xff0c;它们分别对应的DOM结构为&#xff1a; 我们需要将 oldVnode 更新为 newVnode&#xff0c;这时就可以使用双端比较算法了。算法本质上是将新旧节点进行一次交叉比较&#xff0c;尽可能地重复使用已有的节点来达到最小…...

跨界的胜利:机器学习与神经网络的物理之光

近日&#xff0c;2024年诺贝尔物理学奖颁发给了机器学习与神经网络领域的研究者&#xff0c;这是历史上首次出现这样的情况。这项奖项原本只授予对自然现象和物质的物理学研究作出重大贡献的科学家&#xff0c;如今却将全球范围内对机器学习和神经网络的研究和开发作为了一种能…...

容器化技术:Docker的基本概念和使用

在现代软件开发和运维中&#xff0c;容器化技术已经成为一种不可或缺的工具。Docker作为容器化技术的代表&#xff0c;以其轻量级、可移植性和隔离性等特点&#xff0c;赢得了广泛的关注和应用。本文将详细介绍Docker的基本概念和使用方法&#xff0c;帮助读者快速上手Docker容…...

EcoVadis认证内容有哪些?EcoVadis认证申请流程?

EcoVadis认证是一个国际性的可持续发展评估平台&#xff0c;旨在帮助全球企业和供应链评鉴其在环境、社会和治理&#xff08;ESG&#xff09;方面的表现。该认证框架由法国的检验、认证和检测机构必维集团&#xff08;Bureau Veritas&#xff09;创建&#xff0c;得到了众多跨国…...

Windows 搭建 Gitea

一、准备工作 1. 安装 Git&#xff1a;Gitea 依赖 Git 进行代码管理&#xff0c;所以首先需要确保系统中安装了 Git。 下载地址&#xff1a;https://git-scm.com/downloads/win 2. 安装数据库&#xff08;可选&#xff09; 默认情况下&#xff0c;Gitea 使用 SQLite 作为内…...

嵌入式面试——FreeRTOS篇(五) 事件标志组

本篇为&#xff1a;FreeRTOS事件标志组篇 1、事件标志组介绍 答&#xff1a; 事件标志位&#xff1a;用一个位&#xff0c;来表示事件是否发生。 事件标志组是一组事件标志位的合集&#xff0c;可以简单的理解事件标志组&#xff0c;就是一个整数。 2、事件标志组的特点 答&am…...

智能听诊器:宠物健康管理的革命

智能听诊器不仅仅是一个简单的监测工具&#xff0c;它代表了宠物健康管理的一次革命。通过收集和分析宠物的生理数据&#xff0c;智能听诊器能够帮助宠物主人和医生更好地理解宠物的健康需求&#xff0c;从而提供更加个性化的护理方案。 智能听诊器通过高精度的传感器&#xf…...

dfs +剪枝sudoku———poj2676

目录 前言 lowbit函数 数独 suduku 问题描述 输入 输出 问题分析 子网格位置 优化搜索顺序剪枝1 优化搜索顺序剪枝2 可行性剪枝 代码 前言 lowbit函数 这是一个利用二进制位运算取出二进制数最后一位’1‘的函数 数独 数独大家肯定都玩过&#xff0c;…...

机器学习:关联规则:Apriori算法、FP - Growth算法的原理、应用场景及优缺点介绍

一、关联规则算法概述 关联规则挖掘是数据挖掘中的一个重要任务&#xff0c;用于发现数据集中不同项之间的关联关系。 二、Apriori算法 原理 频繁项集生成&#xff1a;Apriori算法基于一个先验原理&#xff0c;即如果一个项集是频繁的&#xff0c;那么它的所有子集也是频繁的…...

从0开始深度学习(7)——线性回归的简洁实现

在从0开始深度学习&#xff08;5&#xff09;——线性回归的逐步实现中&#xff0c;我们手动编写了数据构造模块、损失函数模块、优化器等&#xff0c;但是在现代深度学习框架下&#xff0c;这些已经包装好了 本章展示如果利用深度学习框架简洁的实现线性回归 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生成(仅供学习参考)

前端页面模块修改成可动态生成数据模块&#xff1a; 这些案例展示了如何通过Blade模板将前端页面模块变成可动态生成的模板。通过巧妙使用Blade语法、控制结构、CSS/JS分离、组件复用等技巧&#xff0c;可以大大提高代码的灵活性和复用性。在Laravel的Controller中准备好数据并…...

5.错误处理在存储过程中的重要性(5/10)

错误处理在存储过程中的重要性 引言 在数据库编程中&#xff0c;存储过程是一种重要的组件&#xff0c;它允许用户将一系列SQL语句封装成一个单元&#xff0c;以便重用和简化数据库操作。然而&#xff0c;像任何编程任务一样&#xff0c;存储过程中的代码可能会遇到错误或异常…...

循环冗余码校验CRC码 算法步骤+详细实例计算

通信过程&#xff1a;&#xff08;白话解释&#xff09; 我们将原始待发送的消息称为 M M M&#xff0c;依据发送接收消息双方约定的生成多项式 G ( x ) G(x) G(x)&#xff08;意思就是 G &#xff08; x ) G&#xff08;x) G&#xff08;x) 是已知的&#xff09;&#xff0…...

java 实现excel文件转pdf | 无水印 | 无限制

文章目录 目录 文章目录 前言 1.项目远程仓库配置 2.pom文件引入相关依赖 3.代码破解 二、Excel转PDF 1.代码实现 2.Aspose.License.xml 授权文件 总结 前言 java处理excel转pdf一直没找到什么好用的免费jar包工具,自己手写的难度,恐怕高级程序员花费一年的事件,也…...

Python爬虫实战:研究feedparser库相关技术

1. 引言 1.1 研究背景与意义 在当今信息爆炸的时代,互联网上存在着海量的信息资源。RSS(Really Simple Syndication)作为一种标准化的信息聚合技术,被广泛用于网站内容的发布和订阅。通过 RSS,用户可以方便地获取网站更新的内容,而无需频繁访问各个网站。 然而,互联网…...

Go 语言接口详解

Go 语言接口详解 核心概念 接口定义 在 Go 语言中&#xff0c;接口是一种抽象类型&#xff0c;它定义了一组方法的集合&#xff1a; // 定义接口 type Shape interface {Area() float64Perimeter() float64 } 接口实现 Go 接口的实现是隐式的&#xff1a; // 矩形结构体…...

pam_env.so模块配置解析

在PAM&#xff08;Pluggable Authentication Modules&#xff09;配置中&#xff0c; /etc/pam.d/su 文件相关配置含义如下&#xff1a; 配置解析 auth required pam_env.so1. 字段分解 字段值说明模块类型auth认证类模块&#xff0c;负责验证用户身份&am…...

.Net Framework 4/C# 关键字(非常用,持续更新...)

一、is 关键字 is 关键字用于检查对象是否于给定类型兼容,如果兼容将返回 true,如果不兼容则返回 false,在进行类型转换前,可以先使用 is 关键字判断对象是否与指定类型兼容,如果兼容才进行转换,这样的转换是安全的。 例如有:首先创建一个字符串对象,然后将字符串对象隐…...

代理篇12|深入理解 Vite中的Proxy接口代理配置

在前端开发中,常常会遇到 跨域请求接口 的情况。为了解决这个问题,Vite 和 Webpack 都提供了 proxy 代理功能,用于将本地开发请求转发到后端服务器。 什么是代理(proxy)? 代理是在开发过程中,前端项目通过开发服务器,将指定的请求“转发”到真实的后端服务器,从而绕…...

在Ubuntu24上采用Wine打开SourceInsight

1. 安装wine sudo apt install wine 2. 安装32位库支持,SourceInsight是32位程序 sudo dpkg --add-architecture i386 sudo apt update sudo apt install wine32:i386 3. 验证安装 wine --version 4. 安装必要的字体和库(解决显示问题) sudo apt install fonts-wqy…...

GitFlow 工作模式(详解)

今天再学项目的过程中遇到使用gitflow模式管理代码&#xff0c;因此进行学习并且发布关于gitflow的一些思考 Git与GitFlow模式 我们在写代码的时候通常会进行网上保存&#xff0c;无论是github还是gittee&#xff0c;都是一种基于git去保存代码的形式&#xff0c;这样保存代码…...

如何更改默认 Crontab 编辑器 ?

在 Linux 领域中&#xff0c;crontab 是您可能经常遇到的一个术语。这个实用程序在类 unix 操作系统上可用&#xff0c;用于调度在预定义时间和间隔自动执行的任务。这对管理员和高级用户非常有益&#xff0c;允许他们自动执行各种系统任务。 编辑 Crontab 文件通常使用文本编…...