95、23种设计模式之建造者模式(4/23)

建造者模式(Builder Pattern)是23种经典设计模式中的创建型模式之一,其核心思想是将复杂对象的构建过程与其表示分离,使得同样的构建流程可以生成不同结构或配置的对象。以下从定义、结构、应用场景、优缺点及代码示例展开分析:

一、模式定义

建造者模式通过分步构建复杂对象,将对象的构造逻辑(如部件创建、组装顺序)封装在独立的建造者类中,客户端只需指定建造者类型即可获得最终产品,无需了解内部细节。
类比:如同在餐厅点餐,顾客只需选择套餐类型(如A套餐、B套餐),厨师(建造者)会按固定流程准备食材(部件)并组合成完整餐品(产品)。

二、模式结构

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

1.产品(Product)

复杂对象,由多个部件组成(如汽车由引擎、轮胎、车身等部件构成)。

2.抽象建造者(Builder)

定义创建产品各部件的抽象方法(如buildEngine()、buildWheel()),并提供获取最终产品的方法(如getVehicle())。

3.具体建造者(ConcreteBuilder)

实现抽象建造者接口,具体定义部件的创建和组装逻辑,返回不同配置的产品实例。

4.指挥者(Director)

封装构建流程,调用建造者的方法按固定顺序组装产品(可选角色,客户端也可直接调用建造者)。

三、应用场景

1.复杂对象构造

对象由多个部件构成,且部件创建步骤复杂(如计算机组装需选择CPU、内存、硬盘等)。

2.相同流程不同表示

构建过程稳定,但部件组合方式多样(如汽车可组装为SUV、跑车等不同型号)。

3.隔离构造与使用

客户端无需关心对象内部细节,只需关注最终产品(如通过StringBuilder.append()逐步构建字符串,最后调用toString()获取结果)。

4.可选部件处理

对象包含可选属性,避免使用冗长的构造函数或Setter方法(如通过链式调用设置对象属性)。

四、优缺点分析

1.优点

(1)解耦构建与表示:客户端无需知道产品内部结构,只需指定建造者类型。
(2)扩展性强:新增具体建造者不影响现有代码,符合开闭原则。
(3)控制构建细节:可灵活调整部件创建顺序或条件(如根据配置选择引擎类型)。

2.缺点

(1)类数量增加:需定义抽象建造者、具体建造者等额外类,系统复杂度上升。
(2)维护成本高:若产品内部结构变化,所有建造者均需修改。
(3)适用范围有限:仅适用于部件数量多、构造过程复杂的对象。

五、代码示例(C#)

以下是一个 完整的 C# 建造者模式示例,包含 产品类、抽象建造者、具体建造者、指挥者 和 客户端调用,并支持 链式调用:

using System;// 1. 产品类(Computer)
public class Computer
{public string CPU { get; set; }public string RAM { get; set; }public string Storage { get; set; }public string GPU { get; set; }public bool HasKeyboard { get; set; }public bool HasMouse { get; set; }public override string ToString(){return $@"
Computer Configuration:CPU: {CPU}RAM: {RAM}Storage: {Storage}GPU: {GPU}Keyboard: {(HasKeyboard ? "Included" : "Not Included")}Mouse: {(HasMouse ? "Included" : "Not Included")}";}
}// 2. 抽象建造者(IComputerBuilder)
public interface IComputerBuilder
{IComputerBuilder SetCPU(string cpu);IComputerBuilder SetRAM(string ram);IComputerBuilder SetStorage(string storage);IComputerBuilder SetGPU(string gpu);IComputerBuilder IncludeKeyboard(bool include);IComputerBuilder IncludeMouse(bool include);Computer Build();
}// 3. 具体建造者(GamingComputerBuilder)
public class GamingComputerBuilder : IComputerBuilder
{private Computer _computer = new Computer();public IComputerBuilder SetCPU(string cpu) { _computer.CPU = cpu; return this; }public IComputerBuilder SetRAM(string ram) { _computer.RAM = ram; return this; }public IComputerBuilder SetStorage(string storage) { _computer.Storage = storage; return this; }public IComputerBuilder SetGPU(string gpu) { _computer.GPU = gpu; return this; }public IComputerBuilder IncludeKeyboard(bool include) { _computer.HasKeyboard = include; return this; }public IComputerBuilder IncludeMouse(bool include) { _computer.HasMouse = include; return this; }public Computer Build() { return _computer; }
}// 4. 指挥者(ComputerDirector)
public class ComputerDirector
{public Computer BuildGamingPC(IComputerBuilder builder){return builder.SetCPU("AMD Ryzen 9 5900X").SetRAM("64GB DDR4").SetStorage("2TB NVMe SSD").SetGPU("NVIDIA RTX 3080 Ti").IncludeKeyboard(true).IncludeMouse(true).Build();}public Computer BuildOfficePC(IComputerBuilder builder){return builder.SetCPU("Intel i5").SetRAM("16GB DDR4").SetStorage("512GB SSD").SetGPU("Integrated Graphics").IncludeKeyboard(false).IncludeMouse(false).Build();}
}// 5. 客户端代码
class Program
{static void Main(){// 使用指挥者构建标准配置var director = new ComputerDirector();var builder = new GamingComputerBuilder();Computer gamingPC = director.BuildGamingPC(builder);Computer officePC = director.BuildOfficePC(builder);Console.WriteLine("=== Standard Gaming PC ===");Console.WriteLine(gamingPC);Console.WriteLine("\n=== Standard Office PC ===");Console.WriteLine(officePC);// 直接链式调用自定义配置Computer customPC = new GamingComputerBuilder().SetCPU("Apple M1 Ultra").SetRAM("128GB").SetStorage("8TB SSD").SetGPU("AMD Radeon Pro").IncludeKeyboard(true).Build();Console.WriteLine("\n=== Custom PC ===");Console.WriteLine(customPC);}
}

关键设计点

1.链式调用

通过返回 IComputerBuilder 实现流畅接口(如 SetCPU().SetRAM().Build())。

2.指挥者

封装固定构建流程(如 BuildGamingPC()),适合重复性构造。

3.灵活性

既可通过指挥者快速构建标准配置,也可直接链式调用自定义配置。
适用于需要 分步构建复杂对象 且 支持多种配置 的场景(如电脑、汽车、报表生成等)。

六、模式变体与实际应用

1.链式调用

通过方法返回this实现链式调用(如new Computer.Builder().cpu(“i9”).ram(“32GB”).build()),简化客户端代码。

2.与工厂模式结合

工厂模式关注对象创建,建造者模式关注对象构造过程,两者可结合使用(如先通过工厂获取建造者,再调用建造者组装产品)。

3.JDK中的应用

StringBuilder、StringBuffer均采用建造者模式,通过append()方法逐步构建字符串,最后调用toString()获取结果。

七、总结

建造者模式适用于构造复杂对象的场景,通过解耦构建过程与产品表示,提升代码的灵活性和可维护性。其核心优势在于分步构建和精细控制,但需权衡类数量增加带来的复杂度。在实际开发中,可根据对象复杂度选择是否引入指挥者角色,或直接使用链式调用的简化形式。

在这里插入图片描述

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

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

相关文章

LIA-X - 一张照片生成任意表情肖像动画视频 精准操控面部动作 支持50系显卡 一键整合包下载

LIA-X 是一个可解释的潜在肖像动画生成器,只需要一张照片加一段驱动视频生成任意表情肖像动画, 旨在将驱动视频中的面部动态精细地转移到源肖像上,同时提供对头部、嘴巴和眼睛的精细控制。同时支持图像和视频的编辑任务,比如对头部…

Google 的 Opal:重新定义自动化的 AI 平台

1. 真实世界测试:结果出乎意料 我让 Opal 接受了三项极具挑战性的任务: 1.1. 博客生成器挑战 我的提示:“研究并撰写一篇关于 2 亿美元融资对无代码(no-code)影响的文章。” 发生了什么:Opal 不仅仅是写…

【FreeRTOS】任务通知

任务通知通知状态的三种取值taskNOT_WAITING_NOTIFICATION:任务没有在等待通知taskWAITING_NOTIFICATION:任务在等待通知taskNOTIFICATION_RECEIVED:任务接收到了通知,也被称为 pending(有数据了,待处理)如下面两个场景…

BEV:隐式相机视角转换-----BEVFormer

一、背景 基于imp投影的相机视角转换,对相机的内外参依赖较高,BEV 网格融合固定,可能对小目标不够敏感;考虑通过transformer的方式进行相机的视角转换,BEV query 可以自适应关注关键区域,提高小目标检测&am…

zsh 使用笔记 命令行智能提示 bash智能

目录 安装: 升级: zsh 有什么用? zsh 安装: sudo apt update sudo apt install zsh -y 升级: omz update zsh 有什么用? 相比 bash,zsh 更智能、更方便,常见优势有&#xff…

Laya的适配模式选择

文章目录SCALE_FIXED_AUTOSCALE_SHOWALLSCALE_FULLSCALE_FIXED_HEIGHTSCALE_FIXED_WIDTHSCALE_NOSCALESCALE_EXACTFITSCALE_NOBORDERdemoSCALE_FIXED_AUTO NO.1会透,拉伸能解决官网解释:应用保持设计比例不变,全屏显示全部内容(类似showall&…

Android中flavor的使用

在我的开发中,有这样的需求,有一个项目,需要适配不同的执法仪设备,这些执法仪都是Android系统的,而且有的有系统签名,有的没有,比如我共有四款型号,有三款有系统签名,每款…

如何使用DeepSeek解析长pdf的文本

直接使用python工具解析pdf文件,可能因为格式兼容问题,导致解析出的文本几乎不可读。 这里尝试使用Deepseek解析pdf文件,这里仅考虑文本,不考虑其他要素。 1 解析第一步 将pdf作为附件上传到deepseekchat界面,输入如…

W3C CSS 活动

W3C CSS 活动 引言 CSS(层叠样式表)是现代网页设计中不可或缺的技术之一。W3C(万维网联盟)作为全球互联网标准制定的主要组织,定期举办各类CSS相关的活动,旨在促进CSS技术的发展与普及。本文将详细介绍W3C CSS活动,包括活动内容、参与方式以及活动意义。 活动内容 1…

React Native 与 UniApp 对比

React Native 优点: 由 Facebook 开发维护,社区生态强大 使用 JavaScript/TypeScript 开发,学习曲线相对平缓 真正的原生渲染,性能接近原生应用 支持热重载,开发效率高 可访问所有原生平台 API 大型应用案例丰富(如 Faceboo…

Dijkstra和多层图 0

众所周知&#xff0c;Dijkstra经常拿来解决不带负权和环的单元最短路。我们先来看一下他的实现过程 (由于朴素版用的不多&#xff0c;我们直接上堆优化) 模板 #include<bits/stdc.h> #define mf(x,y) make_pair(x,y)//x距离&#xff0c;y节点 using namespace std; …

【驱动】RK3576:桌面操作系统基本概念

1、桌面操作系统 我们常说的Ubuntu、Debian、麒麟、统信等都是总包工头; 他们把linux内核、根文件系统(遵循 Linux 标准文件系统层次结构FHS)、包管理(软件、库)、桌面环境(GNOME、Xfce等)、初始化系统(Systemd)、各种服务与守护进程、安全组件等整合成一个完整的桌面…

sfc_os!SfcQueueValidationRequest函数分析之sfc_os!IsFileInQueue

第一部分&#xff1a;1: kd> kc# 00 sfc_os!SfcQueueValidationRequest 01 sfc_os!SfcWatchProtectedDirectoriesWorkerThread 02 kernel32!BaseThreadStart1: kd> dvRegVal 0x01129164ChangeType 5vrd 0x012bfef0Status 0n1988337684vrdexisting 0x012bffdc//// if…

100202Title和Input组件_编辑器-react-仿低代码平台项目

文章目录1 开发两个问卷组件1.1 Title组件1.2 Input组件1.3 画布静态展示TItle和Input2 Ajax获取问卷数据&#xff0c;并存储到Redux store2.1 API接口2.2 组件列表存储到Redux store统一管理2.3 重构useLoadQuestionData3 在画布显示问卷列表&#xff0c;点击可选中3.1 Redux获…

设置计划任务自动备份mysql

windows系统下1.创建mysql自动备份脚本mysqlback.bat需将此脚本存放在mysql的bin文件夹下。确保此脚本执行成功了在进行第2步做计划任务。echo off REM 定义备份目录backup_dir、备份的文件名filename set "backup_dirD:\mysqlback" set "filenamemysqlback_%da…

飞机起落架轮轴深孔中间段电解扩孔内轮廓检测 - 激光频率梳 3D 轮廓检测

摘要&#xff1a;飞机起落架轮轴深孔中间段电解扩孔内轮廓检测存在精度要求高、结构复杂等挑战。本文针对电解扩孔特殊工艺特征&#xff0c;探讨激光频率梳 3D 轮廓检测技术的应用&#xff0c;分析其检测原理、技术优势及在轮轴深孔检测中的实践&#xff0c;为电解扩孔内轮廓高…

【软考中级网络工程师】知识点之入侵防御系统:筑牢网络安全防线

目录一、入侵防御系统基础概念1.1 定义与作用1.2 与其他安全设备的关系二、入侵防御系统工作原理剖析2.1 数据包捕获与预处理2.2 深度包检测&#xff08;DPI&#xff09;技术2.3 威胁特征匹配2.4 行为分析与机器学习辅助检测2.5 威胁处理与响应机制三、入侵防御系统功能全面解析…

Python爬虫实战:研究scrapfly-scrapers库,构建电商/新闻/社交媒体数据采集系统

1. 引言 1.1 研究背景与意义 在大数据与人工智能技术深度渗透各行业的背景下,数据已成为企业决策、学术研究、产品创新的核心驱动力。互联网作为全球最大的信息载体,蕴含海量结构化与非结构化数据(如电商商品信息、新闻资讯、社交媒体动态等),其价值挖掘依赖高效的数据采…

Python爬虫反爬检测失效问题的代理池轮换与请求头伪装实战方案

Python爬虫反爬检测失效问题的代理池轮换与请求头伪装实战方案 &#x1f31f; Hello&#xff0c;我是摘星&#xff01; &#x1f308; 在彩虹般绚烂的技术栈中&#xff0c;我是那个永不停歇的色彩收集者。 &#x1f98b; 每一个优化都是我培育的花朵&#xff0c;每一个特性都是…

【原理】C#构造函数可以标记为Static吗

【从UnityURP开始探索游戏渲染】专栏-直达 实例构造函数&#xff08;Instance Constructor&#xff09;不能标记为static但C#提供了一种特殊的‌ 静态构造函数&#xff08;Static Constructor&#xff09;专门用于初始化静态成员。下面依次介绍他们&#xff1a; 1. ‌实例构造…