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

建造者模式(Builder Pattern)

建造者模式(Builder Pattern)是一种创建型设计模式,它主要用于将一个复杂对象的构建与它的表示分离,使得同样的构建过程可以创建不同的表示。这种设计模式的核心思想是将一个复杂对象的构建分解成多个相对简单的步骤,并允许通过不同的方式组合这些步骤来创建不同的对象。以下是关于建造者模式的详细解析:

一、定义与特点

  • 定义: 建造者模式将一个复杂对象的构建与它的表示分离,使得同样的构建过程可以创建不同的表示。

  • 特点:
    1.封装性: 将复杂对象的创建过程封装在独立的建造者类中,使得对象的创建过程更加清晰和易于理解。
    2.灵活性: 通过使用建造者模式,可以灵活地修改对象的创建过程,而不需要修改对象的具体表示。
    3.可复用性: 建造者模式将对象的创建过程分解为多个步骤,并将这些步骤封装在独立的建造者类中,从而提高了代码的可复用性。

二、角色与结构

在建造者模式中,通常包含以下几个角色:

Product(产品类): 表示被构建的复杂对象。它包含多个组成部件的类,以及这些部件的装配方式。
Builder(抽象建造者): 为创建一个产品对象的各个部件指定抽象接口。它不提供具体的实现,而是由子类来实现具体的构建过程。
ConcreteBuilder(具体建造者): 实现Builder接口,完成复杂产品的各个部件的具体创建方法。在构造过程完成后,提供产品的实例。
Director(指挥者): 构造一个使用Builder接口的对象。它主要负责定义构建过程的执行顺序,并通过Builder接口来指导具体建造者完成构建过程。

三、适用场景

建造者模式适用于以下场景:

  1. 创建的对象较复杂,由多个部件构成,各部件面临着复杂的变化,但构件间的建造顺序是稳定的。
  2. 创建复杂对象的算法独立于该对象的组成部分以及它们的装配方式,即产品的构建过程和最终的表示是独立的。
  3. 当需要生成的产品对象有复杂的内部结构,并且这些产品的内部表示被隐藏起来时,可以使用建造者模式。

四、优缺点

  • 优点
    1.封装性好: 将复杂对象的创建过程封装在独立的建造者类中,使得对象的创建过程更加清晰和易于理解。
    2.灵活性高: 可以通过不同的具体建造者来创建不同的产品表示,而不需要修改产品的内部结构和创建过程。
    3.可复用性强: 建造者模式将对象的创建过程分解为多个步骤,并将这些步骤封装在独立的建造者类中,从而提高了代码的可复用性。
  • 缺点
    1.类的数量增多: 由于将对象的创建过程分解为多个步骤,并将这些步骤封装在独立的建造者类中,因此需要创建多个建造者类,从而增加了类的数量。
    2.建造过程复杂: 如果对象的创建过程过于复杂,可能会导致建造者类的建造过程也变得复杂,从而增加了代码的维护难度。

五、示例

以构建汽车为例,假设汽车由引擎、轮胎和车门等多个部件组成。使用建造者模式,可以分别为每种类型的车(如跑车和SUV)提供不同的建造者。这些建造者负责构建汽车的各个部件,并通过指挥者类来确保构建过程的顺序和正确性。最终,客户端可以通过调用指挥者类的方法来获取构建好的汽车对象。
在C#中实现建造者模式,你需要定义几个关键组件:产品(Product)、抽象建造者(Builder)、具体建造者(ConcreteBuilder)以及指挥者(Director)。以下是一个简单的C#示例,展示了如何使用建造者模式来构建不同类型的车辆(如汽车和卡车)。

  1. 定义产品类(Vehicle)
    首先,定义一个产品类,它包含了一些基本的部件和组装这些部件的方法(尽管在建造者模式中,这些方法的实现可能会留空,因为具体的组装过程将由建造者来完成)。
public class Vehicle  
{  public string Engine { get; set; }  public string Wheels { get; set; }  public string Body { get; set; }  // 通常,这里的方法可能用于设置或获取车辆的状态,但在建造者模式中,  // 这些方法可能会被留空或用于验证构建的车辆。  public void Display()  {  Console.WriteLine($"Vehicle with Engine: {Engine}, Wheels: {Wheels}, Body: {Body}");  }  
}
  1. 定义抽象建造者接口(IVehicleBuilder)
    然后,定义一个抽象建造者接口,它声明了构建产品所需的方法。
public interface IVehicleBuilder  
{  void BuildEngine();  void BuildWheels();  void BuildBody();  Vehicle GetVehicle();  
}
  1. 定义具体建造者类(CarBuilder 和 TruckBuilder)
    接下来,为每个类型的产品定义具体的建造者类。这些类实现了抽象建造者接口,并提供了构建产品的具体步骤。
public class CarBuilder : IVehicleBuilder  
{  private Vehicle _vehicle = new Vehicle();  public void BuildEngine()  {  _vehicle.Engine = "V8 Engine";  }  public void BuildWheels()  {  _vehicle.Wheels = "4 Wheels";  }  public void BuildBody()  {  _vehicle.Body = "Sedan Body";  }  public Vehicle GetVehicle()  {  return _vehicle;  }  
}  public class TruckBuilder : IVehicleBuilder  
{  private Vehicle _vehicle = new Vehicle();  public void BuildEngine()  {  _vehicle.Engine = "Diesel Engine";  }  public void BuildWheels()  {  _vehicle.Wheels = "6 Wheels";  }  public void BuildBody()  {  _vehicle.Body = "Truck Body";  }  public Vehicle GetVehicle()  {  return _vehicle;  }  
}
  1. 定义指挥者类(VehicleDirector)
    最后,定义一个指挥者类,它负责控制构建过程。指挥者类持有一个建造者对象的引用,并定义了一个构建产品的步骤列表。
public class VehicleDirector  
{  private IVehicleBuilder _builder;  public VehicleDirector(IVehicleBuilder builder)  {  _builder = builder;  }  public void Construct()  {  _builder.BuildEngine();  _builder.BuildWheels();  _builder.BuildBody();  }  public Vehicle GetVehicle()  {  return _builder.GetVehicle();  }  
}
  1. 客户端代码
    现在,你可以在客户端代码中使用这些类来构建不同类型的车辆了。
class Program  
{  static void Main(string[] args)  {  // 使用CarBuilder构建汽车  IVehicleBuilder carBuilder = new CarBuilder();  VehicleDirector carDirector = new VehicleDirector(carBuilder);  carDirector.Construct();  Vehicle car = carDirector.GetVehicle();  car.Display();  // 使用TruckBuilder构建卡车  IVehicleBuilder truckBuilder = new TruckBuilder();  VehicleDirector truckDirector = new VehicleDirector(truckBuilder);  truckDirector.Construct();  Vehicle truck = truckDirector.GetVehicle();  truck.Display();  }  
}

在这个例子中,建造者模式使得创建不同类型的车辆变得灵活且易于管理。你可以通过添加新的具体建造者类来轻松地扩展系统,以支持更多类型的车辆。

六、总结

建造者模式是一种强大的设计模式,它通过将复杂对象的构建过程与其表示分离,提供了更好的封装性、灵活性和可复用性。在需要创建复杂对象且对象的创建过程需要高度定制化的场景中,建造者模式是一个非常好的选择。

相关文章:

建造者模式(Builder Pattern)

建造者模式(Builder Pattern)是一种创建型设计模式,它主要用于将一个复杂对象的构建与它的表示分离,使得同样的构建过程可以创建不同的表示。这种设计模式的核心思想是将一个复杂对象的构建分解成多个相对简单的步骤,并…...

【MySQL】索引 【下】{聚簇索引VS非聚簇索引/创建主键索引/全文索引的创建/索引创建原则}

文章目录 1.聚簇索引 VS 非聚簇索引经典问题 2.索引操作创建主键索引唯一索引的创建普通索引的创建全文索引的创建查询索引删除索引索引创建原则 1.聚簇索引 VS 非聚簇索引 之前介绍的将所有的数据都放在叶子节点的这种存储引擎对应的就是 InnoDB 默认存储表数据的存储结构。 …...

论文快过(图像配准|Coarse_LoFTR_TRT)|适用于移动端的LoFTR算法的改进分析 1060显卡上45fps

项目地址:https://github.com/Kolkir/Coarse_LoFTR_TRT 创建时间:2022年 相关训练数据:BlendedMVS LoFTR [19]是一种有效的深度学习方法,可以在图像对上寻找合适的局部特征匹配。本文报道了该方法在低计算性能和有限内存条件下的…...

免费发送邮件两种接口方式:SMTP和邮件API

SMTP与邮件API在处理大批量邮件发送时,哪个更稳定? 在现代信息化的社会中,邮件已成为不可或缺的沟通工具。无论是个人还是企业,发送邮件都是日常工作的一部分。AokSend将详细介绍两种常用的免费发送邮件接口方式:SMTP…...

大模型日报 2024-07-30

大模型日报 2024-07-30 大模型资讯 开源AI性能逼近专有领袖,最新基准测试揭示 摘要: Galileo最新的幻觉指数显示,开源AI模型的性能正在迅速逼近专有巨头。这一发现表明,开源AI在技术进步和性能提升方面取得了显著进展,缩小了与专有…...

docker 构建 mongodb

最近需要在虚拟机上构建搭建mongo的docker容器,搞了半天老有错,归其原因,是因为现在最新的mango镜像的启动方式发生了变化,故此现在好多帖子,就是错的。 ok,话不多说: # 拉取最新镜像&#xf…...

LeetCode每日练习 | 二分查找 | 数组 |Java | 图解算法

🙋大家好!我是毛毛张! 🌈个人首页: 神马都会亿点点的毛毛张 📌 你真的刷明白了二分查找吗⁉️记得看毛毛张每个题目中写的【注意细节】⚠️ 文章目录 0.前言🍁1.[704. 二分查找🍍](https://l…...

2024年获客新渠道,大数据爬虫获客:技术实现精准抓取数据资源

**2024年获客新渠道:大数据爬虫获客及技术实现精准抓取数据资源** ### 一、大数据爬虫获客概述 在2024年,随着大数据技术的不断发展和互联网的普及,大数据爬虫获客已经成为企业获取客户信息、实现精准营销的重要渠道。爬虫技术通过自动化程…...

滑模变结构控制仿真实例(s-function代码详解)

目录 一、建立系统数学模型二、控制器设计1. 设计滑模面(切换面)2.设计控制器 u3. 稳定性证明 三、 Matlab 仿真1. s-function 模型2. 主要代码3. 仿真结果(采用符号函数sign(s))4. 仿真结果(采用饱和函数sat(s)) 一、建立系统数学模型 { x ˙ 1 x 2 x ˙ 2 x 3 x ˙ 3 x 1 …...

MySQL处理引擎

MySQL中的数据用各种不同的技术存储在文件(或者内存)中。这些技术中的每一种都 使用不同的存储机制、索引技巧、锁定水平并且最终提供广泛的、不同的功能和能力。通过 选择不同的技术,能够获得额外的速度或者功能,从而改善应用的整体性能。 这些不同的技…...

HTTP 方法详解:GET、POST 和 PUT

HTTP 方法详解:GET、POST 和 PUT HTTP 方法(GET、POST、PUT)用于客户端和服务器之间的通信。它们在输入、输出和传输内容上有显著区别。 1. GET 方法 – 获取资源 用途:从服务器获取资源。 输入: 请求行&#xff…...

被工信部认可的开源软件治理解决方案

近日,工信部网络安全产业发展中心正式发布了“2023年信息技术应用创新解决方案”,开源网安凭借“基于SCA技术开源软件治理解决方案”顺利入选,成为经工信部认可的优秀解决方案,这是开源网安连续两届荣获此荣誉。 工业和信息化部网…...

文件包含漏洞--pyload

文章目录 前言一、pandas是什么?二、使用步骤 1.引入库2.读入数据总结 一.PHP伪协议利用 php://协议 php://filter :用于在读取作用和写入文件时进行过滤和转换操作。 作用1:利用base64编码过滤器读取源码 通常利用文件包含执行php://filte…...

C++包管理之`vcpkg`简介

文章目录 工程文件安装vcpkg安装fmt库安装全局的库安装仅该工程使用的库 在CMake中使用vcpkg通过CMAKE_TOOLCHAIN_FILE使用vcpkg通过CMakePresets.json使用vcpkg 在C开发中,我们经常会使用一些第三方库,比如说Boost、fmt、spdlog等等。这些库的安装和使用…...

【机器学习】必会核函数之:高斯核函数

高斯核函数 1、引言2、高斯核函数2.1 定义2.2 核心原理2.3 应用场景2.4 代码示例3、总结1、引言 在机器学习和数据科学领域,核方法 ( K e r n e l M e t h o d s ) (Kernel Methods) (Kerne...

51单片机和STM32区别

51单片机和 STM32 区别 51单片机和 STM32 是两种常见的微控制器,它们在架构、性能、外设接口、功耗和开发环境等方面有所不同。 1. 架构差异 51单片机基于传统的哈佛总线结构,采用 CISC 架构,而 STM32 基于 ARM Cortex-M 系列的32位处理器核…...

Python 伪随机数生成器

random.sample() 函数原理 在 Python 中,随机数的生成通常依赖于伪随机数生成器(PRNG)。random 模块提供了一个易于使用的接口来生成伪随机数。以下是 random 模块中随机数生成的基本原理和方法: 伪随机数生成器(PRN…...

7.5 grafana上导入模板看图并讲解告警

本节重点介绍 : blackbox_exporter grafana大盘导入和查看告警配置讲解 grafana大盘 grafana 上导入 blackbox_exporter dashboard 地址 https://grafana.com/grafana/dashboards/13659举例图片http总览图value_mapping设置 展示设置阈值,展示不同背景色 告警配…...

BUG解决(vue3+echart报错):Cannot read properties of undefined (reading ‘type‘)

这是 vue3echart5 遇到的报错:Cannot read properties of undefined (reading ‘type‘) 这个问题需要搞清楚两个关键方法: toRaw: 作用:将一个由reactive生成的响应式对象转为普通对象。 使用场景: 用于读取响应式…...

VSCode+git的gitee仓库搭建

​ 在此之前你已经在gitee创建好了账号,并新建了一个仓库。 1. 安装 Visual Studio Code Visual Studio Code 是编辑 Markdown 和站点配置文件的基础,以下将其简称为 VSCode,你可以在它的 官方网站 下载到它。 如若不理解各个版本之间的区别…...

谷歌浏览器插件

项目中有时候会用到插件 sync-cookie-extension1.0.0:开发环境同步测试 cookie 至 localhost,便于本地请求服务携带 cookie 参考地址:https://juejin.cn/post/7139354571712757767 里面有源码下载下来,加在到扩展即可使用FeHelp…...

Zustand 状态管理库:极简而强大的解决方案

Zustand 是一个轻量级、快速和可扩展的状态管理库,特别适合 React 应用。它以简洁的 API 和高效的性能解决了 Redux 等状态管理方案中的繁琐问题。 核心优势对比 基本使用指南 1. 创建 Store // store.js import create from zustandconst useStore create((set)…...

8k长序列建模,蛋白质语言模型Prot42仅利用目标蛋白序列即可生成高亲和力结合剂

蛋白质结合剂(如抗体、抑制肽)在疾病诊断、成像分析及靶向药物递送等关键场景中发挥着不可替代的作用。传统上,高特异性蛋白质结合剂的开发高度依赖噬菌体展示、定向进化等实验技术,但这类方法普遍面临资源消耗巨大、研发周期冗长…...

为什么需要建设工程项目管理?工程项目管理有哪些亮点功能?

在建筑行业,项目管理的重要性不言而喻。随着工程规模的扩大、技术复杂度的提升,传统的管理模式已经难以满足现代工程的需求。过去,许多企业依赖手工记录、口头沟通和分散的信息管理,导致效率低下、成本失控、风险频发。例如&#…...

React19源码系列之 事件插件系统

事件类别 事件类型 定义 文档 Event Event 接口表示在 EventTarget 上出现的事件。 Event - Web API | MDN UIEvent UIEvent 接口表示简单的用户界面事件。 UIEvent - Web API | MDN KeyboardEvent KeyboardEvent 对象描述了用户与键盘的交互。 KeyboardEvent - Web…...

python爬虫:Newspaper3k 的详细使用(好用的新闻网站文章抓取和解析的Python库)

更多内容请见: 爬虫和逆向教程-专栏介绍和目录 文章目录 一、Newspaper3k 概述1.1 Newspaper3k 介绍1.2 主要功能1.3 典型应用场景1.4 安装二、基本用法2.2 提取单篇文章的内容2.2 处理多篇文档三、高级选项3.1 自定义配置3.2 分析文章情感四、实战案例4.1 构建新闻摘要聚合器…...

相机从app启动流程

一、流程框架图 二、具体流程分析 1、得到cameralist和对应的静态信息 目录如下: 重点代码分析: 启动相机前,先要通过getCameraIdList获取camera的个数以及id,然后可以通过getCameraCharacteristics获取对应id camera的capabilities(静态信息)进行一些openCamera前的…...

相机Camera日志分析之三十一:高通Camx HAL十种流程基础分析关键字汇总(后续持续更新中)

【关注我,后续持续新增专题博文,谢谢!!!】 上一篇我们讲了:有对最普通的场景进行各个日志注释讲解,但相机场景太多,日志差异也巨大。后面将展示各种场景下的日志。 通过notepad++打开场景下的日志,通过下列分类关键字搜索,即可清晰的分析不同场景的相机运行流程差异…...

NLP学习路线图(二十三):长短期记忆网络(LSTM)

在自然语言处理(NLP)领域,我们时刻面临着处理序列数据的核心挑战。无论是理解句子的结构、分析文本的情感,还是实现语言的翻译,都需要模型能够捕捉词语之间依时序产生的复杂依赖关系。传统的神经网络结构在处理这种序列依赖时显得力不从心,而循环神经网络(RNN) 曾被视为…...

大数据学习(132)-HIve数据分析

​​​​🍋🍋大数据学习🍋🍋 🔥系列专栏: 👑哲学语录: 用力所能及,改变世界。 💖如果觉得博主的文章还不错的话,请点赞👍收藏⭐️留言&#x1f4…...