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

设计模式五:建造者模式(Builder Pattern)

建造者模式(Builder Pattern)是一种创建型设计模式,用于通过一系列步骤来构建复杂对象。它将对象的构建过程与其表示分离,从而允许相同的构建过程可以创建不同的表示。

建造者模式中的几个角色:

  1. 产品(Product):表示被构建的复杂对象。
  2. 抽象建造者(Builder):定义了构建复杂对象所需的各个步骤,并声明了获取最终产品的方法。
  3. 具体建造者(Concrete Builder):实现了抽象建造者接口,负责实际构建产品的各个部分,并提供获取最终产品的方法。
  4. 指挥者(Director):负责调用具体建造者的方法来构建产品,但不关心具体的构建过程。
  5. 使用建造者模式可以使得构建过程更加灵活,同时可以隐藏复杂对象的构建细节。它适用于需要创建具有多个部分或属性的复杂对象,并希望能够灵活地组合这些部分或属性的场景。

建造者模式适用于以下情况:

  1. 当需要创建一个复杂对象,并且希望能够灵活地配置其属性或部分时,可以使用建造者模式。它允许按照特定的顺序或组合来构建对象的不同部分,从而生成不同的表示。
  2. 当一个类有多个可选参数,并且希望避免使用大量的构造函数或者参数重载时,建造者模式可以解决这个问题。通过使用方法链式调用,每个可选参数都可以在需要的时候设置,从而构建出完整的对象。
  3. 当需要创建的对象由一系列步骤组成,而且希望将这些步骤进行解耦和封装时,可以使用建造者模式。每个具体建造者只关注自己负责的构建步骤,而不必了解其他部分的细节,从而实现了高度的灵活性和可扩展性。
  4. 当需要创建的对象具有复杂的内部结构,其中某些部分的构建过程可能相同,但具体细节又有所不同时,建造者模式非常有用。通过定义抽象建造者和具体建造者,可以让不同的建造者负责构建不同的部分,从而实现代码的复用和解耦。
  5. 建造者模式适用于需要构建复杂对象,并且希望能够灵活地配置其属性或部分的情况。它可以简化对象的创建过程,提高代码的可读性和可维护性。同时,它也能够隐藏复杂对象的构建细节,使得客户端可以专注于业务逻辑而不必关心对象的创建过程。

一个简单的建造者模式的代码实例:

// 产品类
class Car {private String brand;private String model;private int year;public void setBrand(String brand) {this.brand = brand;}public void setModel(String model) {this.model = model;}public void setYear(int year) {this.year = year;}public void display() {System.out.println("Brand: " + brand);System.out.println("Model: " + model);System.out.println("Year: " + year);}
}// 抽象建造者类
abstract class CarBuilder {protected Car car;public void createCar() {car = new Car();}public abstract void buildBrand();public abstract void buildModel();public abstract void buildYear();public Car getCar() {return car;}
}// 具体建造者类
class SedanCarBuilder extends CarBuilder {public void buildBrand() {car.setBrand("Toyota");}public void buildModel() {car.setModel("Camry");}public void buildYear() {car.setYear(2022);}
}// 指挥者类
class CarDirector {private CarBuilder carBuilder;public void setCarBuilder(CarBuilder carBuilder) {this.carBuilder = carBuilder;}public Car getCar() {return carBuilder.getCar();}public void buildCar() {carBuilder.createCar();carBuilder.buildBrand();carBuilder.buildModel();carBuilder.buildYear();}
}// 客户端代码
public class Main {public static void main(String[] args) {CarDirector carDirector = new CarDirector();CarBuilder sedanCarBuilder = new SedanCarBuilder();carDirector.setCarBuilder(sedanCarBuilder);carDirector.buildCar();Car car = carDirector.getCar();car.display();}
}

在上面的代码中,我们首先定义了产品类 Car ,然后定义了抽象建造者类 CarBuilder 和具体建造者类 SedanCarBuilder 。接着定义了指挥者类 CarDirector ,它负责控制具体建造者的构建过程。最后,在客户端代码中,我们通过指挥者来创建一个具体的汽车对象。
这个示例中,我们创建了一个 SedanCarBuilder 来构建一辆轿车的对象。通过使用指挥者 CarDirector ,我们可以按照特定的顺序调用建造者的方法,从而构建出一个完整的汽车对象。最终,我们可以通过 getCar() 方法获取到构建好的汽车对象,并调用 display() 方法显示汽车的属性信息。
通过使用建造者模式,我们可以将对象的构建过程与其表示分离,实现了对象的灵活构建。同时,我们也可以根据需要定义不同的具体建造者类来构建不同类型的对象,从而实现了代码的复用和解耦。

建造者模式的优点:

  1. 分离构建过程和表示:建造者模式将对象的构建过程与其表示分离,使得相同的构建过程可以创建不同的表示。这样可以提高代码的灵活性和可扩展性。
  2. 逐步构建复杂对象:建造者模式允许开发人员逐步构建复杂对象,通过一步步调用建造者的方法来构建对象。这种逐步构建的方式可以确保每个步骤都正确执行,最终得到一个完整且正确的对象。
  3. 更好地控制对象的构建过程:使用建造者模式可以明确控制对象的构建过程,并且可以根据需要对其进行调整。开发人员可以自行定义具体的建造者类,从而按照自己的需求来构建对象。
  4. 提供更好的对象创建过程管理:通过指挥者类来管理对象的创建过程,可以避免客户端直接与具体建造者类交互,从而简化了客户端的使用方式。

建造者模式的缺点:

  1. 增加了代码的复杂度:引入建造者模式会增加额外的代码,包括抽象建造者、具体建造者和指挥者等,从而增加了代码的复杂度和维护成本。
  2. 可能会导致对象过多:由于建造者模式可以逐步构建复杂对象,因此可能会导致创建过多的对象。这些对象之间可能存在较大的差异,从而可能导致系统资源的浪费。

相关文章:

设计模式五:建造者模式(Builder Pattern)

建造者模式(Builder Pattern)是一种创建型设计模式,用于通过一系列步骤来构建复杂对象。它将对象的构建过程与其表示分离,从而允许相同的构建过程可以创建不同的表示。 建造者模式中的几个角色: 产品(Product):表示被构建的复杂…...

C++多线程编程(包含c++20内容)

C多线程编程(包含c20内容) 文章目录 C多线程编程(包含c20内容)线程通过函数指针创建线程通过函数对象创建线程通过lambda创建线程通过成员函数创建线程线程本地存储取消线程自动join线程从线程获得结果 原子操作库原子操作原子智能指针原子引用使用原子类型等待原子变量 互斥互…...

【C语言】通讯录2.0 (动态增长版)

前言 通讯录是一种记录联系人信息的工具,包括姓名、电话号码、电子邮件地址、住址等。 文章的一二三章均于上一篇相同,可以直接看第四章改造内容。 此通讯录是基于通讯录1.0(静态版)的基础上进行改进,请先看系列文字第…...

详解AMQP协议以及JAVA体系中的AMQP

目录 1.概述 1.1.简介 1.2.抽象模型 2.spring中的amqp 2.1.spring amqp 2.2.spring boot amqp 1.概述 1.1.简介 AMQP,Advanced Message Queuing Protocol,高级消息队列协议。 百度百科上的介绍: 一个提供统一消息服务的应用层标准高…...

跨境电商外贸常态下,深度分析Live Market的优势

据统计,今年上半年,面对复杂严峻的外部环境,我国外贸进出口规模在历史同期首次突破20万亿元,展现较强韧性。我国正处于大力支持跨境电商发展的时代节点。在此背景下,无数商家准备抓住时代机遇,将品牌影响力从国内延伸至全世界。同…...

vue2企业级项目(八)

vue2企业级项目&#xff08;八&#xff09; 组件封装&#xff08;二&#xff09; 4、searchForm 创建components/searchForm/index.js import XSearchForm from "./index.vue"; export default XSearchForm;使用案例 <template><div class"wrap"…...

小研究 - 主动式微服务细粒度弹性缩放算法研究(二)

微服务架构已成为云数据中心的基本服务架构。但目前关于微服务系统弹性缩放的研究大多是基于服务或实例级别的水平缩放&#xff0c;忽略了能够充分利用单台服务器资源的细粒度垂直缩放&#xff0c;从而导致资源浪费。为此&#xff0c;本文设计了主动式微服务细粒度弹性缩放算法…...

【雕爷学编程】Arduino动手做(177)---ESP-32 掌控板

37款传感器与执行器的提法&#xff0c;在网络上广泛流传&#xff0c;其实Arduino能够兼容的传感器模块肯定是不止这37种的。鉴于本人手头积累了一些传感器和执行器模块&#xff0c;依照实践出真知&#xff08;一定要动手做&#xff09;的理念&#xff0c;以学习和交流为目的&am…...

使用Gunicorn+Nginx部署Flask项目

部署-开发机上的准备工作 确认项目没有bug。用pip freeze > requirements.txt将当前环境的包导出到requirements.txt文件中&#xff0c;方便部署的时候安装。将项目上传到服务器上的/srv目录下。这里以git为例。使用git比其他上传方式&#xff08;比如使用pycharm&#xff…...

【12】STM32·HAL库开发-STM32时钟系统 | F1/F4/F7时钟树 | 配置系统时钟

目录 1.认识时钟树&#xff08;掌握&#xff09;1.1什么是时钟&#xff1f;1.2认识时钟树&#xff08;F1&#xff09;1.2.1STM32F103时钟树简图1.2.2STM32CubeMX时钟树&#xff08;F103&#xff09; 1.3认识时钟树&#xff08;F4&#xff09;1.3.1F407时钟树1.3.2F429时钟树1.3…...

Kotlin基础(十):函数进阶

前言 本文主要讲解kotlin函数&#xff0c;之前系列文章中提到过函数&#xff0c;本文是kotlin函数的进阶内容。 Kotlin文章列表 Kotlin文章列表: 点击此处跳转查看 目录 1.1 函数基本用法 Kotlin 是一种现代的静态类型编程语言&#xff0c;它在函数的定义和使用上有一些特点…...

计算机视觉(四)神经网络与典型的机器学习步骤

文章目录 神经网络生物神经元人工神经元激活函数导数 人工神经网络“层”的通俗理解 前馈神经网络Delta学习规则前馈神经网络的目标函数梯度下降输出层权重改变量 误差方向传播算法误差传播迭代公式简单的BP算例随机梯度下降&#xff08;SGD&#xff09;Mini-batch Gradient De…...

使用easyui的tree组件实现给角色快捷分配权限功能

这篇文章主要介绍怎么实现角色权限的快捷分配功能&#xff0c;不需要像大多数项目的授权一样&#xff0c;使用类似穿梭框的组件来授权。 具体实现&#xff1a;通过菜单树的勾选和取消勾选来给角色分配权限&#xff0c;在这之前&#xff0c;需要得到角色的菜单树&#xff0c;角色…...

Postman打不开/黄屏/一直转圈/Windows

环境背景 内网环境Postman-win64-8.11.1-Setup.exe 问题描述 电脑重启后&#xff0c;打开Postman后&#xff0c;出现加载弹窗&#xff1a;Preparing your workspaces…This might take a few minutes&#xff1b; 等待数分钟后&#xff0c;还是没有反应&#xff0c;于是关闭…...

使用SVM模型完成分类任务

SVM&#xff0c;即支持向量机&#xff08;Support Vector Machine&#xff09;&#xff0c;是一种常见的机器学习算法&#xff0c;用于分类和回归分析。SVM的基本思想是将数据集映射到高维空间中&#xff0c;在该空间中找到一个最优的超平面&#xff0c;将不同类别的数据点分开…...

计算机毕设 深度学习实现行人重识别 - python opencv yolo Reid

文章目录 0 前言1 课题背景2 效果展示3 行人检测4 行人重识别5 其他工具6 最后 0 前言 &#x1f525; 这两年开始毕业设计和毕业答辩的要求和难度不断提升&#xff0c;传统的毕设题目缺少创新和亮点&#xff0c;往往达不到毕业答辩的要求&#xff0c;这两年不断有学弟学妹告诉…...

开发经验分享之:import引入包和@Autowired注入类有什么区别

大家好&#xff0c;我是三叔&#xff0c;很高兴这期又和大家见面了&#xff0c;一个奋斗在互联网的打工人。 import 和 Autowired 想必大家在 Java 开发中使用频率最多的关键字之一了把&#xff0c;这篇博客将解释这两个概念的区别和作用&#xff0c;帮助你更好地理解它们在Ja…...

MySQL和Oracle区别

由于SQL Server不常用&#xff0c;所以这里只针对MySQL数据库和Oracle数据库的区别 (1) 对事务的提交 MySQL默认是自动提交&#xff0c;而Oracle默认不自动提交&#xff0c;需要用户手动提交&#xff0c;需要在写commit;指令或者点击commit按钮 (2) 分页查询 MySQL是直接在SQL…...

QT--day6(人脸识别、图像处理)

人脸识别&#xff1a; /***********************************************************************************头文件****************************************************************************************/#ifndef WIDGET_H #define WIDGET_H#include <QWidget>…...

深度学习:常用优化器Optimizer简介

深度学习&#xff1a;常用优化器Optimizer简介 随机梯度下降SGD带动量的随机梯度下降SGD-MomentumSGDWAdamAdamW 随机梯度下降SGD 梯度下降算法是使权重参数沿着整个训练集的梯度方向下降&#xff0c;但往往深度学习的训练集规模很大&#xff0c;计算整个训练集的梯度需要很大…...

RocketMQ延迟消息机制

两种延迟消息 RocketMQ中提供了两种延迟消息机制 指定固定的延迟级别 通过在Message中设定一个MessageDelayLevel参数&#xff0c;对应18个预设的延迟级别指定时间点的延迟级别 通过在Message中设定一个DeliverTimeMS指定一个Long类型表示的具体时间点。到了时间点后&#xf…...

通过Wrangler CLI在worker中创建数据库和表

官方使用文档&#xff1a;Getting started Cloudflare D1 docs 创建数据库 在命令行中执行完成之后&#xff0c;会在本地和远程创建数据库&#xff1a; npx wranglerlatest d1 create prod-d1-tutorial 在cf中就可以看到数据库&#xff1a; 现在&#xff0c;您的Cloudfla…...

Debian系统简介

目录 Debian系统介绍 Debian版本介绍 Debian软件源介绍 软件包管理工具dpkg dpkg核心指令详解 安装软件包 卸载软件包 查询软件包状态 验证软件包完整性 手动处理依赖关系 dpkg vs apt Debian系统介绍 Debian 和 Ubuntu 都是基于 Debian内核 的 Linux 发行版&#xff…...

CMake基础:构建流程详解

目录 1.CMake构建过程的基本流程 2.CMake构建的具体步骤 2.1.创建构建目录 2.2.使用 CMake 生成构建文件 2.3.编译和构建 2.4.清理构建文件 2.5.重新配置和构建 3.跨平台构建示例 4.工具链与交叉编译 5.CMake构建后的项目结构解析 5.1.CMake构建后的目录结构 5.2.构…...

关于nvm与node.js

1 安装nvm 安装过程中手动修改 nvm的安装路径&#xff0c; 以及修改 通过nvm安装node后正在使用的node的存放目录【这句话可能难以理解&#xff0c;但接着往下看你就了然了】 2 修改nvm中settings.txt文件配置 nvm安装成功后&#xff0c;通常在该文件中会出现以下配置&…...

基于数字孪生的水厂可视化平台建设:架构与实践

分享大纲&#xff1a; 1、数字孪生水厂可视化平台建设背景 2、数字孪生水厂可视化平台建设架构 3、数字孪生水厂可视化平台建设成效 近几年&#xff0c;数字孪生水厂的建设开展的如火如荼。作为提升水厂管理效率、优化资源的调度手段&#xff0c;基于数字孪生的水厂可视化平台的…...

【Web 进阶篇】优雅的接口设计:统一响应、全局异常处理与参数校验

系列回顾&#xff1a; 在上一篇中&#xff0c;我们成功地为应用集成了数据库&#xff0c;并使用 Spring Data JPA 实现了基本的 CRUD API。我们的应用现在能“记忆”数据了&#xff01;但是&#xff0c;如果你仔细审视那些 API&#xff0c;会发现它们还很“粗糙”&#xff1a;有…...

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

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

微信小程序云开发平台MySQL的连接方式

注&#xff1a;微信小程序云开发平台指的是腾讯云开发 先给结论&#xff1a;微信小程序云开发平台的MySQL&#xff0c;无法通过获取数据库连接信息的方式进行连接&#xff0c;连接只能通过云开发的SDK连接&#xff0c;具体要参考官方文档&#xff1a; 为什么&#xff1f; 因为…...

是否存在路径(FIFOBB算法)

题目描述 一个具有 n 个顶点e条边的无向图&#xff0c;该图顶点的编号依次为0到n-1且不存在顶点与自身相连的边。请使用FIFOBB算法编写程序&#xff0c;确定是否存在从顶点 source到顶点 destination的路径。 输入 第一行两个整数&#xff0c;分别表示n 和 e 的值&#xff08;1…...