C# 建造者模式(Builder Pattern)详细讲解
一、什么是建造者模式?
建造者模式(Builder Pattern)是一种创建型设计模式,它通过将一个复杂对象的构建过程与其表示分离,使得同样的构建过程可以创建不同的表示。这个模式主要应用于那些构建过程复杂且涉及多个步骤的场景,特别适合于需要灵活配置且逐步构建的对象。
1.1. 设计模式分类
设计模式(Design Patterns)分为三大类:
- 创建型模式(Creational Patterns):关注如何创建对象的设计模式。
- 结构型模式(Structural Patterns):关注如何通过组合对象来构建更大的结构。
- 行为型模式(Behavioral Patterns):关注对象之间如何进行交互和职责分配。
建造者模式属于创建型模式,它的目的是通过分步构建,避免构造复杂对象时需要过多的参数或复杂的配置。
1.2. 为什么使用建造者模式?
在许多情况下,我们会遇到这样的问题:某些对象非常复杂,构建它们时需要多个步骤,这些步骤又可能是可选的,或者需要根据不同的需求使用不同的配置。直接通过构造函数来构建这样复杂的对象,不仅代码重复,而且不易扩展。建造者模式通过将构建过程分解成多个步骤,使得对象的创建过程更具灵活性,且客户端代码更加简洁。
二、建造者模式的结构
建造者模式的核心思想是将对象的创建过程分成多个步骤,而这些步骤可以独立进行组合。 建造者模式一般包含以下几个组成部分:
2.1. 组成部分
- 产品类(Product):
- 产品类是最终构建出来的对象,它通常是一个复杂对象,包含多个部件和属性。
- 抽象建造者(Builder):
- 抽象建造者声明了构建产品的各个步骤,例如设置不同的部件,获取最终的产品等。通常是一个接口或者抽象类,提供一组构建方法。
- 具体建造者(Concrete Builder):
- 具体建造者实现了抽象建造者的方法,并为构建产品的每一步提供具体的实现。它管理着产品的组成部分,并在最后生成产品。
- 指挥者(Director):
- 指挥者负责定义构建过程的顺序,调用具体建造者的方法来完成复杂对象的构建。指挥者并不关心产品的具体细节,而是将构建过程委托给建造者来完成。
三、建造者模式的工作流程
建造者模式的工作流程通常如下:
- 客户创建一个指挥者对象,并通过它指定所需的建造者(通常是某个具体的建造者类)。
- 指挥者会按照顺序调用建造者中的各个方法,逐步构建产品。
- 具体建造者负责逐步构建产品的各个部分(如设置不同的部件或配置)。
- 最终产品在构建完成后返回给客户,客户可以根据需求使用该产品。
四、示例:构建一个复杂的汽车对象
4.1. 定义产品类:Car
在本例中,我们要构建的产品是一个复杂的 Car 类。该类有多个部件和属性,包括引擎类型、车轮数量、是否有 GPS、是否有天窗等。
public class Car
{public string Engine { get; set; }public int Wheels { get; set; }public bool HasGPS { get; set; }public bool HasSunroof { get; set; }public override string ToString(){return $"Car [Engine: {Engine}, Wheels: {Wheels}, GPS: {HasGPS}, Sunroof: {HasSunroof}]";}
}
Car 类有四个主要属性,分别是:Engine(引擎类型),Wheels(车轮数),HasGPS(是否有 GPS),HasSunroof(是否有天窗)。这些属性是构成汽车的基本部分。
4.2. 创建抽象建造者:ICarBuilder
ICarBuilder 是一个接口,定义了构建汽车的步骤(例如构建引擎、车轮、GPS 和天窗等):
public interface ICarBuilder
{void BuildEngine();void BuildWheels();void BuildGPS();void BuildSunroof();Car GetResult();
}
ICarBuilder 接口提供了五个方法:
BuildEngine():构建引擎。BuildWheels():构建车轮。BuildGPS():构建 GPS。BuildSunroof():构建天窗。GetResult():返回最终构建好的产品Car对象。
4.3. 创建具体建造者:SportsCarBuilder
SportsCarBuilder 类是一个具体的建造者,它实现了 ICarBuilder 接口,负责具体构建一个运动型汽车:
public class SportsCarBuilder : ICarBuilder
{private Car _car = new Car();public void BuildEngine(){_car.Engine = "V8 Engine"; // 运动型车的引擎}public void BuildWheels(){_car.Wheels = 4; // 标准运动型车有4个轮子}public void BuildGPS(){_car.HasGPS = true; // 运动型车需要 GPS}public void BuildSunroof(){_car.HasSunroof = true; // 运动型车有天窗}public Car GetResult(){return _car; // 返回构建好的汽车}
}
在 SportsCarBuilder 中,每个方法实现了具体的构建步骤,逐步设置汽车的属性。最后,GetResult() 方法返回构建完成的 Car 对象。
4.4. 创建指挥者:CarDirector
指挥者类 CarDirector 负责按照一定顺序调用建造者的方法来构建汽车:
public class CarDirector
{private ICarBuilder _carBuilder;public CarDirector(ICarBuilder carBuilder){_carBuilder = carBuilder;}public Car ConstructCar(){_carBuilder.BuildEngine();_carBuilder.BuildWheels();_carBuilder.BuildGPS();_carBuilder.BuildSunroof();return _carBuilder.GetResult();}
}
CarDirector 类使用 ICarBuilder 来完成汽车的构建过程。ConstructCar() 方法按照固定的顺序调用建造者的构建方法,最后返回构建好的汽车。
4.5. 客户端代码:如何使用建造者模式
客户端代码通过创建一个具体的建造者(如 SportsCarBuilder),然后将它传递给指挥者 CarDirector,最终得到一个构建好的汽车。
class Program
{static void Main(string[] args){// 创建具体的建造者ICarBuilder carBuilder = new SportsCarBuilder();// 创建指挥者CarDirector director = new CarDirector(carBuilder);// 指挥者构建汽车Car car = director.ConstructCar();// 输出结果Console.WriteLine(car);}
}
输出:
Car [Engine: V8 Engine, Wheels: 4, GPS: True, Sunroof: True]
在客户端中,我们通过 CarDirector 来构建一个带有 V8 引擎、4 个轮子、GPS 和天窗的运动型车。
五、建造者模式的优点与缺点
5.1. 优点
-
解耦产品的构建与表示:
- 建造者模式将对象的构建过程与最终的表示(对象的不同状态)分开,允许你独立于对象的具体表示方式构建复杂对象。
-
构建过程灵活:
- 同一个构建过程可以生成不同的产品。例如,你可以使用不同的建造者(如
SportsCarBuilder和SUVCarBuilder)来构建不同类型的汽车。
- 同一个构建过程可以生成不同的产品。例如,你可以使用不同的建造者(如
-
代码清晰、可维护:
- 每个具体建造者只负责构建特定类型的产品,避免了复杂的构造函数或多个参数的使用,使得代码结构更加清晰。
-
适合复杂产品的创建:
- 当对象的构建过程复杂,且各个部件之间有多种组合方式时,建造者模式非常适合。
5.2. 缺点
-
需要更多的类:
- 由于每个不同的建造者需要实现一个接口,并为每个产品提供具体实现,因此在产品种类很多时,可能会创建多个建造者类,导致类的数量增加。
-
不能直接使用“简单对象”:
- 对于一些简单的对象,使用建造者模式可能会显得有些“过度设计”,特别是当对象没有复杂的构建步骤时,简单的构造函数可能更为直接。
六、总结
建造者模式是一种非常有效的设计模式,它提供了一种灵活的方式来构建复杂对象。通过分解构建过程并将其与具体的表示分离,建造者模式能够创建不同类型的对象,同时保持代码的清晰性和可维护性。在 C# 中,建造者模式适用于复杂对象的构建、逐步配置以及需要灵活控制构建过程的场景。
总结关键点:
- 产品类:定义最终构建出来的复杂对象。
- 建造者接口:定义构建对象的步骤。
- 具体建造者:负责实现建造步骤并返回产品。
- 指挥者:负责控制构建过程的顺序,调用建造者进行具体操作。
如果你需要在 C# 中处理复杂对象的创建,并且对象的构建步骤可能变化,或者存在多个变种,建造者模式将是一个非常好的选择。
相关文章:
C# 建造者模式(Builder Pattern)详细讲解
一、什么是建造者模式? 建造者模式(Builder Pattern)是一种创建型设计模式,它通过将一个复杂对象的构建过程与其表示分离,使得同样的构建过程可以创建不同的表示。这个模式主要应用于那些构建过程复杂且涉及多个步骤的…...
Android自动化测试工具
细解自动化测试工具 Airtest-CSDN博客 以下是几种常见的Android应用自动化测试工具: Appium:支持多种编程语言,如Java、Python、Ruby、JavaScript等。可以用于Web应用程序和原生应用程序的自动化测试,并支持iOS和Android平台。E…...
【蓝桥杯】24省赛:数字串个数
思路 本质是组合数学问题: 9个数字组成10000位数字有9**10000可能 不包括3的可能8**10000 不包括7的可能8**10000 既不包括3也不包括77**10000 根据容斥原理:结果为 9 ∗ ∗ 10000 − 8 ∗ ∗ 10000 − 8 ∗ ∗ 10000 7 ∗ ∗ 10000 9**10000 - 8**10…...
SpringBoot中使用kaptcha生成验证码
简介 kaptcha是谷歌开源的简单实用的验证码生成工具。通过设置参数,可以自定义验证码大小、颜色、显示的字符等等。 Maven引入依赖 <!-- https://mvnrepository.com/artifact/pro.fessional/kaptcha --><dependency><groupId>pro.fessional<…...
解密乐天音乐如何通过抗指纹浏览器刷变现
作者:药尘-韩立----->🚀🌍❤️( hanli068 ) 专栏:反反爬技术 日期:2025年3月15日 原创声明:本文为作者原创,未经允许不得转载 在音乐流媒体平台(“日本乐天音乐”)中…...
自定义tiptap插件
本文为开发开源项目的真实开发经历,感兴趣的可以来给我的项目点个star,谢谢啦~ 具体博文介绍: 开源|Documind协同文档(接入deepseek-r1、支持实时聊天)Documind 🚀 一个支持实时聊天和接入 - 掘…...
软考网络安全专业
随着信息技术的迅猛发展,网络安全问题日益凸显,成为社会各界普遍关注的焦点。在这样的背景下,软考网络安全专业应运而生,为培养高素质的网络安全人才提供了有力支撑。本文将对软考网络安全专业进行深入剖析,探讨其在信…...
蓝桥杯嵌入式赛道复习笔记1(led点亮)
前言 基础的文件创建,参赛资源代码的导入,我就不说了,直接说CubeMX的配置以及代码逻辑思路的书写,在此我也预祝大家人人拿国奖 理论讲解 原理图简介 1.由于存在PC8引脚到PC15引脚存在冲突,那么官方硬件给的解决方案…...
订单超时自动取消功能如何设计
在一个 Java 电商项目中,订单超时自动取消功能可以通过多种方式设计和实现。常见的实现方式包括使用定时任务(例如 ScheduledExecutorService 或 Spring 的 Scheduled 注解)或者基于事件驱动的方式(如使用消息队列)。以…...
FPGA为何要尽量减少组合逻辑的使用
在FPGA设计中,组合逻辑的使用确实需要谨慎,尤其是要尽量减少它的复杂性。这并不是因为组合逻辑本身不好,而是因为它在实际应用中容易引发一系列问题,而这些问题往往与FPGA的设计哲学和硬件特性相冲突。让我从几个关键点来和你聊聊…...
六十天前端强化训练之第十七天React Hooks 入门:useState 深度解析
欢迎来到编程星辰海的博客讲解 看完可以给一个免费的三连吗,谢谢大佬! 目录 一、知识讲解 1. Hooks 是什么? 2. useState 的作用 3. 基本语法解析 4. 工作原理 5. 参数详解 a) 初始值设置方式 b) 更新函数特性 6. 注意事项 7. 类组…...
芯科科技推出的BG29超小型低功耗蓝牙®无线SoC,是蓝牙应用的理想之选
具有扩大的内存和超低功耗特性的超小型BG29是互联健康设备的理想之选 低功耗无线领域内的领导性创新厂商Silicon Labs(亦称“芯科科技”,NASDAQ:SLAB)今日宣布:推出全新的第二代无线开发平台产品BG29系列无线片上系统…...
联想小新 Pro16 锐龙版本 type c 充电掉速降频问题
小新Pro-16 2021 锐龙版 Type-C接口连接电源适配器卡顿降频的解决方案 通过网盘分享的文件:小新Pro-16 2021 锐龙版 Type-C接口连接电源适配器卡顿降频的解决方案.zip 链接: https://pan.baidu.com/s/1713s9AO5QC31bdsf8g1ZIw?pwd1234 提取码: 1234 --来自百度网盘…...
export、export default 和 module.exports 深度解析
文章目录 1. 模块系统概述1.1 模块系统对比1.2 模块加载流程 2. ES Modules2.1 export 使用2.2 export default 使用2.3 混合使用 3. CommonJS3.1 module.exports 使用3.2 exports 使用 4. 对比分析4.1 语法对比4.2 使用场景 5. 互操作性5.1 ES Modules 中使用 CommonJS5.2 Com…...
qwen2.5-vl多机多卡分布式部署
记录一下工作中进行多机多卡部署qwen2.5-vl多模态大模型踩过的坑 第一个天坑就是官方提供的镜像qwenllm/qwenvl:2.5-cu121有问题,在titan显卡会抛出cuda error:no kernel image is availabe for execution on the device. 这是cuda内核与GPU不兼容的问题,…...
tsfresh:时间序列特征自动提取与应用
tsfresh:时间序列特征自动提取与应用 本文系统介绍了 tsfresh 技术在 A 股市场数据分析与量化投资中的应用。从基础特征提取到高级策略开发,结合实战案例,详细讲解了如何利用 tsfresh 构建量化投资策略,并优化风险控制,…...
C++Primer学习(7.1 定义抽象数据类型)
类的基本思想是数据抽象(data abstraction)和封装(encapsulation)。数据抽象是种依赖于接口(interface)和实现(implementation)分离的编程(以及设计)技术。类的接口包括用户所能执行的操作:类的实现则包括类的数据成员、负责接口实现的函数体以及定义类所需的各种私有函数。 封…...
【PHP】新版本特性记录(持续更新)
文章目录 前言PHP 7.01)NULL合并运算符:??2)参数、返回值支持类型声明3)太空船操作符:<>4)通过 define 定义常量数组5)匿名类实例化6)字符串里使用\u转义unicode codepoint …...
《蓝耘容器全栈技术指南:企业级云原生与异构计算实战大全》
在数字化转型的浪潮中,容器技术已成为企业构建云原生架构的核心引擎,而蓝耘容器凭借其轻量化内核、异构计算支持及混合云调度能力,正成为企业级应用的首选方案。本文基于《蓝耘容器全栈技术指南》,结合实战案例与技术原理…...
【红黑树】—— 我与C++的不解之缘(二十五)
前言 学习了avl树,现在来学习红黑树。 一、什么是红黑树 红黑树是一颗平衡二叉搜索树,它每一个节点增加了一个存储位表示节点的颜色,可以是红色或者黑色。 相比较于AVL树,红黑树也是一个自平衡二叉搜索树,但是它与AVL树…...
驾驭 DeepSeek 科技之翼,翱翔现代学习新天际
在当今这个信息爆炸的时代,学习的方式和途径正在经历着前所未有的变革。人工智能技术的飞速发展,为我们的学习带来了全新的机遇和挑战。DeepSeek 作为一款强大的大语言模型,凭借其卓越的性能和丰富的功能,为现代学习注入了新的活力…...
DeepSeek本地部署 (Windows+Ollama+Docker Desktop+ RAGFlow)
适用场景: 1、商城的小机器人自动根据实际情况回复 2、需要7*24小时运行在线回复,如:在线购物、在线咨询、在线招生等 3、无人值守环境 2025年1月,DeepSeek 正式发布 DeepSeek-R1 推理大模型,DeepSeek-R1 成本价格低…...
SPI驱动(八) -- SPI_DAC设备驱动程序
文章目录 参考资料:一、编写设备树二、 编写驱动程序三、编写测试APP四、Makefile五、上机实验 参考资料: 参考资料: 内核头文件:include\linux\spi\spi.h内核文档:Documentation\spi\spidevDAC芯片手册:…...
MySQL 衍生表(Derived Tables)
在SQL的查询语句select …. from …中,跟在from子句后面的通常是一张拥有定义的实体表,而有的时候我们会用子查询来扮演实体表的角色,这个在from子句中的子查询会返回一个结果集,这个结果集可以像普通的实体表一样查询、连接&…...
Day16:最小的k个数
仓库管理员以数组 stock 形式记录商品库存表,其中 stock[i] 表示对应商品库存余量。请返回库存余量最少的 cnt 个商品余量,返回 顺序不限。 示例 1: 输入:stock [2,5,7,4], cnt 1 输出:[2]示例 2: 输入…...
MinIo前后端实现
这几天想玩玩Minio,整体来说简单使用起来不复杂(当然也有可能是我配置的太少了) Minio下载 我是通过Dokcer在虚拟机上下载的(Docker真好用啊) 拉取Minio镜像 docker pull minio/minio启动Minio容器 docker run -d …...
HarmonyOS NEXT开发进阶(十二):build-profile.json5 文件解析
文章目录 一、前言二、Hvigor脚本文件三、任务与任务依赖图四、多模块管理4.1 静态配置模块 五、分模块编译六、配置多目标产物七、配置APP多目标构建产物八、定义 product 中包含的 target九、拓展阅读 一、前言 编译构建工具DevEco Hvigor(以下简称Hvigor&#x…...
利用 OpenCV 库进行实时目标物体检测
一、代码概述 此代码利用 OpenCV 库实现了基于特征匹配的实时物体检测系统。通过摄像头捕获实时视频帧,将其与预先加载的参考图像进行特征匹配,从而识别出视频帧中是否存在与参考图像匹配的物体。 二、环境依赖 OpenCV:用于图像处理、特征提…...
深度学习笔记(37周)
目录 摘要 Abstracts 1. 介绍 2. 相关工作 3. 模型 3.1 时序段网络TSN 3.2 学习时序段网络 4. 训练结果 5. 结论 摘要 本周阅读的论文是《Temporal Segment Networks: Towards Good Practices for Deep Action Recognition》。作者主要想通过较少的训练样本ÿ…...
Vue2+Vant2 项目初学
Vant 2 - Mobile UI Components built on Vue Vue.js 安装 | 菜鸟教程 // 通过脚手架安装 // 在新项目中使用 Vant 时,推荐使用 Vue 官方提供的脚手架 Vue Cli 创建项目并安装 Vant。 // # 安装 Vue Cli // npm install -g vue/cli // # 创建一个项目 // vue …...
