设计模式之建造者(Builder)模式

目录

1、什么是建造者Builder模式?

2、建造者Builder模式的利与弊

3、建造者Builder模式的应用场景

4、建造者模式中的指导者(Director)有什么作用?

5、建造者Builder模式与其他模式的关系

小结


1、什么是建造者Builder模式?

Builder模式是一种创建型设计模式,用于将复杂对象的构建过程和表示分离,使得同样的构建过程可以创建不同的表示。建造者模式又称为生成器模式,主要用于对复杂对象的构建及初始化,它可以将多个简单的组件对象按顺序一步步组装起来,最终完成一个复杂的成品对象。与工厂系列模式不同的是,建造者模式的主要目的在于把烦琐的构建过程从不同对象中抽离出来,使其脱离并独立于产品类与工厂类,最终实现用同一套标准的制造工序能够产出不同的产品

在生活中,一个常见的例子是建筑领域的房屋建造。我们可以将房屋的建造过程看作是使用Builder模式来创建房屋对象的过程。

假设我们需要建造一座房子,房子由多个组成部分(例如地基、楼层、墙壁、窗户等)组成,并且每个部分都有多个属性(例如地基的深度、楼层的高度、墙壁的材料等)。

使用Builder模式,我们可以定义一个HouseBuilder类作为建造者,它负责创建和组装房子的各个部分。HouseBuilder类可以有一些方法来设置房子的各个属性,例如setFoundationDepth(int depth)、setFloorHeight(int height)等。

另外,我们还可以定义一个House类作为最终构建的产品。House类包含了房子的所有属性,并提供了访问这些属性的方法。

下面是一个简化的示例代码:

// 房子类
public class House {
    private int foundationDepth;
    private int floorHeight;
    private String wallMaterial;

    // 构造函数和访问方法省略

    // ...
}

// 建造者类
public class HouseBuilder {
    private House house;

    public HouseBuilder() {
        house = new House();
    }

    public void setFoundationDepth(int depth) {
        house.setFoundationDepth(depth);
    }

    public void setFloorHeight(int height) {
        house.setFloorHeight(height);
    }

    public void setWallMaterial(String material) {
        house.setWallMaterial(material);
    }

    public House build() {
        return house;
    }
}

// 使用Builder模式创建房子对象
public class Main {
    public static void main(String[] args) {
        HouseBuilder builder = new HouseBuilder();
        builder.setFoundationDepth(10);
        builder.setFloorHeight(3);
        builder.setWallMaterial("Brick");

        House house = builder.build();

        // 使用房子对象进行后续操作
        // ...
    }
}

在上述示例中,HouseBuilder类负责创建和设置房子的各个属性,最后通过build()方法返回构建好的House对象。这样,我们可以根据需要灵活地设置房子的各个部分,并且可以通过调用build()方法来获取最终的房子对象。

建造者模式的结构图示:

图片来源:设计模式-生成器(Builder) - 知乎

 图片来源:设计模式-生成器(Builder) - 知乎

2、建造者Builder模式的利与弊

Builder模式具有以下优点

  1. 隔离复杂对象的构建过程:Builder模式将复杂对象的构建过程与其表示分离,使得可以独立地构建不同表示的对象。这样可以简化构建过程,提高可读性和维护性。

  2. 提供灵活的构建方式:通过定义不同的Builder或者使用方法链式调用,可以按需设置对象的各个属性,从而灵活地构建对象。可以根据需要组合不同的属性,生成不同的对象实例。

  3. 支持构建过程的逐步完善:Builder模式可以支持逐步完善构建过程,即在Builder中逐步添加设置方法,最后调用build方法返回最终的对象。这种方式可以方便地扩展构建过程,适应不同的需求。

  4. 避免构造函数参数过多:当一个类的构造函数参数过多时,使用Builder模式可以避免构造函数的参数列表过长,提高代码的可读性。

Builder模式的一些缺点

  1. 增加了类的复杂度:引入了Builder类和多个setter方法,增加了类的复杂度和代码量。

  2. 对象构建过程的冗余:Builder模式会创建一个Builder对象来构建目标对象,可能会导致额外的对象创建开销。

  3. 不适用于简单对象:如果目标对象的属性较少,构建过程相对简单,使用Builder模式可能不是最优选择,会增加代码量和复杂度。

需要根据具体情况来权衡使用Builder模式的利弊。在复杂对象的构建过程中,特别是当对象具有大量属性或者构建过程需要逐步完善时,Builder模式可以提供一种灵活、可读性高的解决方案。

3、建造者Builder模式的应用场景

  1. 构建复杂对象:当需要构建的对象具有多个属性,并且构建过程较为复杂时,可以考虑使用Builder模式。例如,构建包含大量配置选项的文档生成器、图形界面中的复杂组件等。

  2. 避免重叠构造函数:当一个类需要多个构造函数来支持不同的对象初始化方式时,可以使用Builder模式来避免创建过多的重叠构造函数,并提供更清晰的对象构建方法。

  3. 创建不可变对象:当需要创建不可变(Immutable)对象时,Builder模式可以很好地与不可变对象的设计原则结合,通过Builder来设置对象的属性,最终构建出不可变的对象实例。

  4. 流式接口(Fluent Interface):Builder模式可以用于创建流式接口,使得客户端代码可以使用链式调用的方式来设置对象的属性,从而提高代码的可读性和简洁性。

  5. 多个构建过程:当需要支持多种构建过程,或者需要逐步完善构建过程时,Builder模式可以提供一种灵活的解决方案,支持根据不同需求构建不同表示的对象。

总的来说,Builder模式适用于需要构建复杂对象、有多个可选参数或需要逐步完善构建过程的情况。通过使用Builder模式,可以将对象的构建过程分离出来,提高灵活性和可读性。

4、建造者模式中的指导者(Director)有什么作用?

在建造者模式中,指导者(Director)起到了协调和组织的作用。它负责控制构建过程,按照特定的顺序调用建造者的方法来构建对象。

指导者的主要作用有以下几点:

  1. 定义构建顺序:指导者确定了构建过程中各个步骤的顺序和调用方式。它知道哪些方法应该在何时被调用,以保证对象的正确构建。

  2. 解耦客户端与具体构建过程:指导者将构建对象的过程封装起来,并与具体的建造者解耦。客户端不需要直接与建造者进行交互,而是通过指导者来完成对象的构建。

  3. 简化客户端代码:指导者隐藏了构建细节,使得客户端可以更简洁地调用构建过程。客户端只需要与指导者进行交互,并传递必要的参数,而无需关心具体的构建过程。

指导者的实现原理通常是通过将建造者作为参数进行注入,并在内部调用建造者的方法来完成构建过程。指导者根据具体需求和建造者的能力来决定调用哪些方法以及调用顺序。

具体实现上,指导者可以提供一个统一的构建方法,接收建造者作为参数,并按照预定的顺序调用建造者的方法来构建对象。也可以根据需要提供一系列的构建方法,每个方法负责调用建造者的特定方法,以完成特定的构建步骤。

通过指导者的存在,客户端可以更简单地调用构建方法,而无需关心具体的构建细节和顺序,从而实现了构建过程的解耦和简化。

5、建造者Builder模式与其他模式的关系

该片段引自:Builder

1. 许多设计从使用Factory方法(不那么复杂,通过子类更可定制)开始,并向抽象工厂、原型或生成器(更灵活,但更复杂)发展。
2. Builder专注于逐步构建复杂的对象。抽象工厂专门创建相关对象的族。Abstract Factory会立即返回产品,而Builder允许在获取产品之前运行一些额外的构造步骤
3. 在创建复杂的复合树时可以使用Builder,因为可以对其构建步骤进行编程以递归工作。
4. 您可以将Builder和Bridge结合起来:director类扮演抽象的角色,而不同的构建器充当实现。
5. 抽象工厂、构建者和原型都可以实现为Singleton。

小结

Builder 模式的关键是其中的 Director 对象并不直接返回对象,而是通过分步进行对象的创建。在这里 Director 可以提供一个默认的返回对象的接口(即返回通用的复杂对象的创建,不指定或者特定唯一指定BuildPart中的参数)。

通过使用Builder模式,可以避免在构造函数或者setter方法中传入大量参数,并且可以更加清晰地组织和管理复杂对象的构建过程。

参考:

精讲设计模式-Builder模式-CSDN博客

设计模式-生成器(Builder) - 知乎

大白话建造者模式(Builder Pattern) - 张有路 - 博客园

Builder

设计模式系列3 - builder模式 - 知乎


感谢阅读,码字不易,多谢点赞!如有不当之处,欢迎反馈指出,感谢!

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

如若内容造成侵权/违法违规/事实不符,请联系我们进行投诉反馈qq邮箱809451989@qq.com,一经查实,立即删除!

相关文章

【华为OD题库-037】跳房子2-java

题目 跳房子,也叫跳飞机,是一种世界性的儿童游戏游戏。参与者需要分多个回合按顺序跳到第1格直到房子的最后一格,然后获得一次选房子的机会,直到所有房子被选完,房子最多的人获胜。 跳房子的过程中,如果有踩…

外部网关协议_边界网关协议BGP

一.边界网关协议BGP的基本概念 边界网关协议(Border Gateway Protocol,BGP)属于外部网关协议EGP这个类别,用于自治系统AS之间的路由选择协议。由于在不同AS内度量路由的“代价”(距离、带宽、费用等)可能不同,因此对于…

SQL Server 百万数据查询优化技巧三十则

点击上方蓝字关注我 互联网时代的进程越走越深,使用MySQL的人也越来越多,关于MySQL的数据库优化指南很多,而关于SQL SERVER的T-SQL优化指南看上去比较少,近期有学习SQLSERVER的同学问到SQL SERVER数据库有哪些优化建议&#xff1f…

【基础知识】AB软件RSLinx的版本说明

哈喽,大家好,我是雷工! 之前对AB的软件了解比较少,在工作中未接触过,最近一次现场勘察时,有很多中控系统都是AB的,借此机会对AB软件有了些许了解。 一、RSLinx是什么软件? RSLinx是…

微服务实战系列之签名Sign

前言 昨日恰逢“小雪”节气,今日寒风如约而至。清晨的马路上,除了洋洋洒洒的落叶,就是熙熙攘攘的上班族。眼看着,暖冬愈明显了,叶子来不及泛黄就告别了树。变化总是在不经意中发生,容不得半刻糊涂。 上集博…

洛谷 P1883 函数

P1883 函数 - 洛谷 | 计算机科学教育新生态 (luogu.com.cn) Error Curves - 洛谷 | 计算机科学教育新生态 (luogu.com.cn) 这两题是一模一样的,过一题水两题。 分析 主要难点在于证明F(x)是一个单峰函数可以被三分,但是我随便画了几个f(x)之后发现好像…

2023人形机器人行业海外科技研究:从谷歌看机器人大模型进展

今天分享的是人形机器人系列深度研究报告:《2023人形机器人行业海外科技研究:从谷歌看机器人大模型进展》。 (报告出品方:华鑫证券) 报告共计:26页 大模型是人形机器人的必备要素 长期来看,人…

大数据分析与应用实验任务九

大数据分析与应用实验任务九 实验目的 进一步熟悉pyspark程序运行方式; 熟练掌握pysaprkRDD基本操作相关的方法、函数,解决基本问题。 实验任务 进入pyspark实验环境,打开命令行窗口,输入pyspark,完成下列任务&am…

Vue3中如何响应式解构 props

目录 1,前言2,解决2.1,利用插件,实现编译时转换2.2,toRef 和 toRefs 1,前言 Vue3 中为了保持响应性,始终需要以 props.x 的方式访问这些 prop。这意味着不能够解构 defineProps 的返回值&#…

linux的基础命令

文章目录 linux的基础命令一、linux的目录结构(一)Linux路径的描述方式 二、Linux命令入门(一)Linux命令基础格式 三、ls命令(一)HOME目录和工作目录(二)ls命令的参数1.ls命令的-a选…

ChatGLM2-6B微调过程说明文档

参考文档: ChatGLM2-6B 微调(初体验) - 知乎 环境配置 下载anaconda,版本是Anaconda3-2023.03-0-Linux-x86_64.sh,其对应的python版本是3.10,试过3.7和3.11版本的在运行时都报错。 执行下面的命令安装anaconda sh Anaconda3-202…

Django之Cookie与Session,CBV加装饰器

前言 会话跟踪技术 在一个会话的多个请求中共享数据,这就是会话跟踪技术。例如在一个会话中的请求如下:  请求银行主页; 请求登录(请求参数是用户名和密码);请求转账(请求参数与转账相关的数…

winlogbeat采集windows日志

下载链接 https://www.elastic.co/cn/downloads/past-releases/winlogbeat-7-16-2 配置文件 # ---------------------------- Elasticsearch Output ---------------------------- output.elasticsearch:# Array of hosts to connect to.hosts: ["192.168.227.160:9200&…

wagtail-安装配置

系列文章目录 文章目录 系列文章目录安装虚拟环境安装wagtail查看安装后的包 创建wagtail项目安装依赖迁移创建超级用户运行项目 安装虚拟环境 https://blog.csdn.net/gsl371/article/details/117917857 安装wagtail (wagenv) C:\djproject\wagprj>pip list Package V…

Mac下载的软件显示文件已损坏,如何解决文件已损坏问题,让文件可以正常运行

Mac下载的软件显示文件已损坏,如何解决文件已损坏问题,让文件可以正常运行 设备/引擎:Mac(11.6)/Mac Mini 开发工具:终端 开发需求:让显示已损坏的文件顺利安装到电脑 大家肯定都遇到过下载…

geoserver发布tif矢量数据图层

cesium加载上传至geoserver的tif矢量数据_cesium加载tiff-CSDN博客 geoserver安装及跨域问题解决方案:geoserver安装及跨域问题解决方案_geoserver 跨域_1 1王的博客-CSDN博客 将TIF上传至geoserver 启动geoserver服务,并进入geoserver主页。 1. 新建…

【Java 进阶篇】Redis持久化之RDB:数据的安全守护者

Redis,作为一款高性能的键值存储系统,支持多种持久化方式,其中RDB(Redis DataBase)是其最常用的一种。RDB可以将当前时刻的数据快照保存到磁盘,以便在Redis重启时快速恢复数据。本文将深入探讨RDB的原理、配…

走近科学之《MySQL 的秘密》

走近科学之《MySQL 的秘密》 mysql 存储引擎、索引、执行计划、事务、锁、分库分表、优化 1、存储引擎(storage engines) 存储引擎规定了数据存储时的不同底层实现,如存储机制、索引、锁、事务等。 可以通过 show engines 命令查看当前服务…

web前端之若依框架图标对照表、node获取文件夹中的文件名,并通过数组返回文件名、在html文件中引入.svg文件、require、icon

MENU 前言效果图htmlJavaScripstylenode获取文件夹中的文件名 前言 需要把若依原有的icon的svg文件拿到哦&#xff01; 注意看生成svg的路径。 效果图 html <div id"idSvg" class"svg_box"></div>JavaScrip let listSvg [404, bug, build, …

TypeScript 学习笔记 第三部分 贪吃蛇游戏

尚硅谷TypeScript教程&#xff08;李立超老师TS新课&#xff09; 1. 创建开发环境 创建工程&#xff0c;使用学习笔记的第二部分安装css部分 npm i -D less less-loader css-loader style-loader对css部分处理&#xff0c;能够运行在低版本浏览器 npm i -D postcss postcss…