设计模式-建造者模式

建造者模式是一种创建型设计模式,旨在将一个复杂对象的构建过程与其表示分离,使得同样的构建过程可以创建不同的表示。它适用于以下场景:

  • 当对象的创建过程非常复杂,包含多个步骤或参数时。
  • 当需要创建的对象具有多个组成部分,且这些部分的组合方式可能不同时。
  • 当希望创建过程与对象的具体表示解耦时。

核心思想

建造者模式通过以下方式实现对象的创建:

  1. 将复杂对象的构建过程分解为多个步骤:每个步骤负责构建对象的一部分。
  2. 引入一个建造者类(Builder):负责定义构建步骤的接口,并实现具体的构建逻辑。
  3. 引入一个指挥者类(Director):负责控制构建过程的顺序,但不涉及具体的构建细节。
  4. 最终产品(Product):通过建造者模式构建的复杂对象。

通过这种方式,建造者模式将对象的构建过程与对象本身解耦,使得构建过程更加灵活和可扩展。

建造者模式的结构

建造者模式通常包含以下角色:

  • 产品(Product)
    最终要构建的复杂对象通,常包含多个组成部分。
  • 抽象建造者(Builder)
    定义构建产品的各个步骤的接口。通常包含多个方法,每个方法负责构建产品的一个部分。
  • 具体建造者(Concrete Builder)
    实现抽象建造者接口,提供具体的构建逻辑。负责创建和组装产品的各个部分。
  • 指挥者(Director)
    负责控制构建过程的顺序。调用建造者的方法,按照特定顺序构建产品。
  • 客户端(Client)
    创建指挥者和建造者对象,并通过指挥者构建最终产品。

建造者模式的优点

  • 分离构建过程与表示
    建造者模式将对象的构建过程与对象本身分离,使得构建过程更加灵活。

  • 易于扩展
    可以通过添加新的具体建造者来支持新的产品类型,而无需修改现有代码。

  • 更好的控制构建过程
    指挥者类可以精确控制构建过程的顺序和步骤。

  • 代码复用性高
    相同的构建过程可以用于创建不同的产品。

建造者模式的缺点

  • 增加了代码复杂性
    需要定义多个类(建造者、指挥者等),增加了系统的复杂性。

  • 适用于复杂对象
    如果对象构建过程非常简单,使用建造者模式可能会显得冗余。

建造者模式的应用场景

  1. 构建复杂对象
    例如,构建一个包含多个组成部分的电脑、汽车或房屋。

  2. 构建过程需要分步骤进行
    例如,生成一个包含多个步骤的文档或报告。

  3. 需要构建多个不同的表示
    例如,构建不同配置的电脑(游戏电脑、办公电脑等)。

建造者模式实现示例

以下是一个简单的建造者模式实现示例,假设我们要构建一个复杂的“电脑”对象,电脑由 CPU、内存、硬盘和显卡等部分组成。

(1)产品类(Product)

public class Computer {private String cpu;private String memory;private String hardDisk;private String gpu;// Setters and Getterspublic void setCpu(String cpu) { this.cpu = cpu; }public void setMemory(String memory) { this.memory = memory; }public void setHardDisk(String hardDisk) { this.hardDisk = hardDisk; }public void setGpu(String gpu) { this.gpu = gpu; }@Overridepublic String toString() {return "Computer [cpu=" + cpu + ", memory=" + memory + ", hardDisk=" + hardDisk + ", gpu=" + gpu + "]";}
}

(2)抽象建造者类(Builder)

public interface ComputerBuilder {void buildCpu();void buildMemory();void buildHardDisk();void buildGpu();Computer getResult();
}

(3)具体建造者类(Concrete Builder)

public class GamingComputerBuilder implements ComputerBuilder {private Computer computer;public GamingComputerBuilder() {this.computer = new Computer();}@Overridepublic void buildCpu() {computer.setCpu("Intel i9");}@Overridepublic void buildMemory() {computer.setMemory("32GB DDR5");}@Overridepublic void buildHardDisk() {computer.setHardDisk("1TB SSD");}@Overridepublic void buildGpu() {computer.setGpu("NVIDIA RTX 4090");}@Overridepublic Computer getResult() {return computer;}
}

(4)指挥者类(Director)

public class ComputerDirector {private ComputerBuilder builder;public ComputerDirector(ComputerBuilder builder) {this.builder = builder;}public void construct() {builder.buildCpu();builder.buildMemory();builder.buildHardDisk();builder.buildGpu();}
}

(5)客户端代码(Client)

public class Client {public static void main(String[] args) {// 创建具体建造者ComputerBuilder builder = new GamingComputerBuilder();// 创建指挥者ComputerDirector director = new ComputerDirector(builder);// 构建产品director.construct();// 获取最终产品Computer computer = builder.getResult();System.out.println(computer);}
}

建造者模式与工厂模式的区别

工厂模式:关注对象的创建,但不关心对象的构建过程。

建造者模式:关注对象的构建过程,特别是复杂对象的构建。

通过建造者模式,可以更好地管理和控制复杂对象的构建过程,使代码更加清晰和可维护。

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

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

相关文章

【Idea】 xml 文本粘贴保持原有文本的缩进格式

Idea xml 文本粘贴保持原有文本的缩进格式 在使用 IntelliJ IDEA 2018 版本中的 MyBatis 时,粘贴 SQL 语句会自动对齐,此时需要进行相关设置来禁用此功能。 setting——>Editor——>Code Style——>XML 勾选“Keep white spaces”

Unity 和 Python 的连接(通过SocketIO)附源码

在游戏或者项目开发中,Unity 通常用于创建前端,而 Python 则因其强大的数据处理能力常被用作后端。通过 Socket.IO,我们可以轻松地实现 Unity 和 Python 的实时通信。本文将介绍如何通过 Socket.IO 连接 Unity 和 Python,并附上完…

[IP]UART

UART 是一个简易串口ip,用户及配置接口简单。 波特率从9600至2000000。 该 IP 支持以下特性: 异步串行通信:标准 UART 协议(1 起始位,8 数据位,1 停止位,无奇偶校验)。 参数化配置…

vue2实现可拖拽菜单栏,及根据菜单内容自动扩展宽度

分为两个功能 基本的html: <el-scrollbarid"leftmenu"v-resize"MuneResize"wrap-class"scrollbar-wrapper"><el-menu:default-active"activeMenu":collapse"isCollapse":background-color"variables.menuBg&…

【软件工程】03_软件需求分析

3.1 系统分析 1. 系统分析概述 系统分析是一组统称为计算机系统工程的活动。它着眼于所有的系统元素,而非仅仅局限于软件。系统分析主要探索软件项目的目标、市场预期、主要的技术指标等,其目的在于帮助决策者做出是否进行软件项目立项的决定。 2. 可行性分析(Feasibility …

父组件中循环生成多个子组件时,有且只有最后一个子组件的watch对象生效问题及解决办法

提示&#xff1a;父组件中循环生成多个子组件时&#xff0c;有且只有最后一个子组件的watch对象生效问题及解决办法 文章目录 [TOC](文章目录) 前言一、问题二、解决方法——使用function函数代替箭头函数()>{}总结 前言 ‌‌‌‌‌问题&#xff1a;子组件用that解决watch无…

SpringMVC(八)Knife4j 接口文档

目录 一 基础使用 1 配置pom.xml相关依赖 2 项目配置 3 输入指定路径&#xff08;http://localhost:8080/doc.html&#xff09; 二 一些使用方法 1 Tag 2 Operation 3 Schema 4 Parameter 5 可以根据需求来设置 补充&#xff1a;日期的格式化 Knife4j 是基于 Swag…

二分算法--整数二分

二分算法–整数二分 假如给定一个整数序列&#xff0c;{ a 1 a_1 a1​, a 2 a_2 a2​, a 3 a_3 a3​, …, a n a_n an​} 我们将整个数列根据某个元素 a x a_x ax​将数列分成左右两个部分&#xff08;某一部分可以包含 a x a_x ax​&#xff09; 首先我们定义一个mid 如…

有效的括号 力扣20

一、题目 二、思路 这题算是栈的经典应用。 主要有三种情况&#xff1a; 第一种情况&#xff1a;已经遍历完了字符串&#xff0c;但是栈不为空&#xff0c;说明有相应的左括号没有右括号来匹配&#xff0c;所以return false 第二种情况&#xff1a;遍历字符串匹配的过程中&…

Nuxt3 使用 ElementUI Plus报错问题

本地正常&#xff0c;打包上线异常 解决方式&#xff1a;官方组件需要被包裹一层&#xff0c;如以下示例&#xff1a; <ClientOnly> </ClientOnly>

uniapp vue3项目定义全局变量,切换底部babar时根据条件刷新页面

前言 uniapp项目中&#xff0c;每个tabbar页面来回点时候&#xff0c;不会触发页面更新。但是有时页面上有数据发生改变需要更新模版时&#xff0c;就得能及时的通知到页面。如果在onshow生命周期里每次都调用异步请求更新数据&#xff0c;有些不合理&#xff0c;况且页面有时…

vulnhub-Hackme-隧道建立、SQL注入、详细解题、思路清晰。

vulnhub-Hackme-隧道建立、SQL注入、详细解题、思路清晰。 一、信息收集 2025.3.14 PM 12&#xff1a;18 1、主机发现 arp-scan -l nmap -sn 192.168.66.0/24 2、端口扫描 1、nmap --min-rate 10000 -p- 192.168.66.182 -oA port 查看所有开放端口2、map -sS -sV 192.168.6…

20250317笔记本电脑在ubuntu22.04下使用acpi命令查看电池电量

20250317笔记本电脑在ubuntu22.04下使用acpi命令查看电池电量 2025/3/17 18:05 百度&#xff1a;ubuntu查看电池电量 百度为您找到以下结果 ubuntu查看电池电量 在Ubuntu操作系统中&#xff0c;查看电池电量通常可以通过命令行或者图形界面来完成。下面是一些常见的方法&…

openEuler系统迁移 Docker 数据目录到 /home,解决Docker 临时文件占用大问题

根据错误信息 write /var/lib/docker/tmp/...: no space left on device&#xff0c;问题的根源是 根分区&#xff08;/&#xff09;的磁盘空间不足&#xff0c;而非 /home 分区的问题。以下是详细解释和解决方案&#xff1a; 问题原因分析 Docker 临时文件占用根分区空间&…

Java 大视界 -- Java 大数据在智能政务舆情引导与公共危机管理中的应用(138)

&#x1f496;亲爱的朋友们&#xff0c;热烈欢迎来到 青云交的博客&#xff01;能与诸位在此相逢&#xff0c;我倍感荣幸。在这飞速更迭的时代&#xff0c;我们都渴望一方心灵净土&#xff0c;而 我的博客 正是这样温暖的所在。这里为你呈上趣味与实用兼具的知识&#xff0c;也…

Deepseek API+Python测试用例一键生成与导出-V1.0.2【实现需求文档图片识别与用例生成自动化】

在测试工作中&#xff0c;需求文档中的图片&#xff08;如界面设计图、流程图&#xff09;往往是测试用例生成的重要参考。然而&#xff0c;手动提取图片并识别内容不仅耗时&#xff0c;还容易出错。本文将通过一个自研小工具&#xff0c;结合 PaddleOCR 和大模型&#xff0c;自…

搭建opensbi+kernel+rootfs及基本设备驱动开发流程

目录 一.编译qemu 运行opensbikernelrootfs 1.编译qemu-9.1.1 2.安装riscv64编译器 3. 编译opensbi 4.编译kernel 5.编译rootfs 设备驱动开发流程 1.安装 RISC-V 交叉编译工具链 2.驱动开发准备 3.编写简易中断控制器驱动&#xff08;PLIC&#xff09;​ 4.配置内核…

16.使用读写包操作Excel文件:XlsxWriter 包

一 XlsxWriter 的介绍 XlsxWriter 只能写入 Excel 文件。 OpenPyXL 和 XlsxWriter 的区别在笔记 15 。 二 如何使用 XlsxWriter 1.导包 import datetime as dtimport xlsxwriterimport excel 2.实例化工作簿 book xlsxwriter.Workbook("xlxswriter.xlsx") book.clo…

LeetCode 124.二叉树中的最大路径和

题目&#xff1a; 二叉树中的 路径 被定义为一条节点序列&#xff0c;序列中每对相邻节点之间都存在一条边。同一个节点在一条路径序列中 至多出现一次 。该路径 至少包含一个 节点&#xff0c;且不一定经过根节点。 路径和 是路径中各节点值的总和。 给你一个二叉树的根节点…

【Dubbo+Zookeeper】——SpringBoot+Dubbo+Zookeeper知识整合

&#x1f3bc;个人主页&#xff1a;【Y小夜】 &#x1f60e;作者简介&#xff1a;一位双非学校的大二学生&#xff0c;编程爱好者&#xff0c; 专注于基础和实战分享&#xff0c;欢迎私信咨询&#xff01; &#x1f386;入门专栏&#xff1a;&#x1f387;【MySQL&#xff0…