设计模式五:建造者模式(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. 可能会导致对象过多:由于建造者模式可以逐步构建复杂对象,因此可能会导致创建过多的对象。这些对象之间可能存在较大的差异,从而可能导致系统资源的浪费。

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

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

相关文章

SpringCloud学习路线(13)——分布式搜索ElasticSeach集群

前言 单机ES做数据存储,必然面临两个问题:海量数据的存储,单点故障。 如何解决这两个问题? 海量数据的存储问题: 将索引库从逻辑上拆分为N个分片(shard),存储到多个节点。单点故障…

Golang之路---02 基础语法——流程控制(if-else , switch-case , for-range , defer)

流程控制 条件语句——if-else if 条件 1 {分支 1 } else if 条件 2 {分支 2 } else if 条件 ... {分支 ... } else {分支 else }注: Golang编译器,对于 { 和 } 的位置有严格的要求,它要求 else if (或 else)和 两边…

Python正则表达式re模块的相关知识积累与博文汇总

正则表达式的内容很多,也很灵活和强大,有必须做下记录,进行汇总。 01-初学Python的re模块的正则表达式的常用方法与常见问题记录 链接1:https://blog.csdn.net/wenhao_ir/article/details/125960370 链接2:https://b…

Mysql 查询统计最近12个月的数据

包括当月: SELECTt1.yf AS month,count( t2.uuid ) AS total FROM(SELECTDATE_FORMAT(( CURDATE()), %Y-%m ) AS yf UNIONSELECTDATE_FORMAT(( CURDATE() - INTERVAL 1 MONTH ), %Y-%m ) AS yf UNIONSELECTDATE_FORMAT(( CURDATE() - INTERVAL 2 MONTH ), %Y-%m ) AS yf UNION…

F5 LTM 知识点和实验 2-负载均衡基础概念

第二章:负载均衡基础概念 目标: 使用网页和TMSH配置virtual servers,pools,monitors,profiles和persistence等。查看统计信息 基础概念: Node一个IP地址。是创建pool池的基础。可以手工创建也可以自动创…

基于canvas画布的实用类Fabric.js的使用

目录 前言 一、Fabric.js简介 二、开始 1、引入Fabric.js 2、在main.js中使用 3、初始化画布 三、方法 四、事件 1、常用事件 2、事件绑定 3、事件解绑 五、canvas常用属性 六、对象属性 1、基本属性 2、扩展属性 七、图层层级操作 八、复制和粘贴 1、复制 2…

Redis常用命令

目录 Redis通用命令 进入Redis 1.进入redis容器 2.进入redis-cli 查询Redis中储存的key 删除key 查询key的过期时间,以毫秒为单位返回 key 的剩余的过期时间 查询key的数据类型 Redis数据结构 Redis数据查询 1.string 查询key对应的值 设置key对应的值 2.list 查…

【ARM 常见汇编指令学习 3 -- ARM64 无符号位域提取指令 UBFX】

文章目录 ARM64 无符号位域提取指令 上篇文章:ARM 常见汇编指令学习 2 – 存储指令 STP 与 LDP 下篇文章:ARM 常见汇编指令学习 4 – ARM64 比较指令 cbnz 与 b.ne 区别 ARM64 无符号位域提取指令 在代码中如何监控寄存器的某1bit, 或者某几…

ACL原理

ACL原理 ACL是一种用于控制网络设备访问权限的技术,可以通过配置ACL来限制特定用户、应用程序或网络设备对网络资源的访问。 1、ACL(Access Control List) 2、ACL是一种包过滤技术。 3、ACL基于IP包头的IP地址、四层TCP/UDP头部的端口号、…

磁盘均衡器:HDFS Disk Balancer

HDFS Disk Balancer 背景产生的问题以及解决方法 hdfs disk balancer简介HDFS Disk Balancer功能数据传播报告 HDFS Disk Balancer开启相关命令 背景 相比较于个人PC,服务器一般可以通过挂载多块磁盘来扩大单机的存储能力在Hadoop HDFS中,DataNode负责最…

canvas实现图片平移,缩放的例子

最近有个水印预览的功能&#xff0c;需要用到canvas 绘制&#xff0c;canvas用的不是很熟&#xff0c;配合chatAI 完成功能。 效果如下 代码如下 原先配置是响应式的&#xff0c;提出来了就不显示操作了&#xff0c;模拟值都写死的 界面给大家参考阅读。 <!DOCTYPE html…

Spring AOP 的概念及其作用

一、什么是 Spring AOP&#xff1f; 在介绍 Spring AOP 之前&#xff0c;首先要了解一下什么是 AOP &#xff1f; AOP &#xff08; Aspect Oriented Programming &#xff09;&#xff1a;面向切面编程&#xff0c;它是一种思想&#xff0c; 它是对某一类事情的集中处 理 。…

软件测试面试题——接口自动化测试怎么做?

面试过程中&#xff0c;也问了该问题&#xff0c;以下是自己的回答&#xff1a; 接口自动化测试&#xff0c;之前做过&#xff0c;第一个版本是用jmeter 做的&#xff0c;1 主要是将P0级别的功能接口梳理出来&#xff0c;根据业务流抓包获取相关接口&#xff0c;并在jmeter中跑…

【前端知识】React 基础巩固(四十三)——Effect Hook

React 基础巩固(四十三)——Effect Hook 一、Effect Hook的基本使用 Effect Hook 用来完成一些类似class中生命周期的功能。 在使用类组件时&#xff0c;不管是渲染、网路请求还是操作DOM&#xff0c;其逻辑和代码是杂糅在一起的。例如我们希望把计数器结果显示在标签上&…

8.事件对象

8.1获取事件对象 ●事件对象是什么 也是个对象&#xff0c;这个对象里有事件触发时的相关信息 例如&#xff1a;鼠标点击事件中&#xff0c;事件对象就存了鼠标点在哪个位置等信息 ●使用场景 可以判断用户按下哪个键&#xff0c;比如按下回车键可以发布新闻 可以判断鼠标点击…

【Java|golang】143. 重排链表---快慢指针

给定一个单链表 L 的头节点 head &#xff0c;单链表 L 表示为&#xff1a; L0 → L1 → … → Ln - 1 → Ln 请将其重新排列后变为&#xff1a; L0 → Ln → L1 → Ln - 1 → L2 → Ln - 2 → … 不能只是单纯的改变节点内部的值&#xff0c;而是需要实际的进行节点交换。 …

CentOS7.3 安装 docker

亲测、截图 阿里云服务器 文章目录 更新源2345 启动开机自启 更新源 sudo yum update -y2 sudo yum install -y yum-utils device-mapper-persistent-data lvm23 sudo yum-config-manager --add-repo https://download.docker.com/linux/centos/docker-ce.repo4 sudo yum …

【软件测试】性能测试工具- LoadRunner的介绍和使用

目录 1. LoadRunner是什么2. LoadRunner环境搭建3. LoadRunner三大组件4. LoadRunner脚本录制4.1 WebTous项目介绍启动WebTous项目访问WebTous项目相关配置 4.2 脚本录制新建脚本录制脚本运行脚本 4.3 脚本加强插入事务插入集合点插入检查点插入日志字符串比较 1. LoadRunner是…

【奥比中光Gemini 2L快速上门】

奥比中光Gemini 2L快速上手 目录 奥比中光Gemini 2L快速上手[TOC](目录) 一、下载配置环境1.1 官网下载SDK1.2 配置环境 二、测试2.1 在bin中运行示例2.2 配置cmake 三、CMAKE3.1 CmakeLists.txt中各设置的意义 一、下载配置环境 1.1 官网下载SDK 进入官网&#xff0c;下载名…

MySQL中锁的简介——行级锁

1.行级锁概念及分类 可通过以下语句查看意向锁和行锁的加锁情况&#xff1a; select object_schema,object_name,index_name,lock_type,lock_mode,lock_data from performance_schema.data_locks;InnoDB的行锁是针对于索引加的锁&#xff0c;不通过索引条件检索数据&#xff0…