设计模式-创建型-04-建造者模式
1、盖房项目需求
- 1)需要建房子:这一过程为打桩、砌墙、封顶
- 2)房子有各种各样的,比如普通房,高楼,别墅,各种房子的过程虽然一样,但是要求不要相同的
- 3)请编写程序,完成需求
传统方式

public abstract class AbsHouse {protected abstract void piling();protected abstract void walling();protected abstract void capping();public void build() {piling();walling();capping();}
}public class NormalRoom extends AbsHouse {@Overrideprotected void piling() {System.out.println("普通房打桩...");}@Overrideprotected void walling() {System.out.println("普通房砌墙...");}@Overrideprotected void capping() {System.out.println("普通房封顶...");}
}public class HighRise extends AbsHouse {@Overrideprotected void piling() {System.out.println("高楼打桩...");}@Overrideprotected void walling() {System.out.println("高楼砌墙...");}@Overrideprotected void capping() {System.out.println("高楼封顶...");}
}public class Villa extends AbsHouse {@Overrideprotected void piling() {System.out.println("别墅打桩...");}@Overrideprotected void walling() {System.out.println("别墅砌墙...");}@Overrideprotected void capping() {System.out.println("别墅封顶...");}
}
问题分析
- 1)优点是比较好理解,简单易操作
- 2)设计的程序结构,过于简单,没有设计缓存层对象,程序的扩展和维护不好。也就是说,这种设计方案把产品(即:房子)和创建产品的过程(即:建房子流程)封装在一起,耦合性增强了
- 3)解决方案:将产品和产品建造过程解耦 ==> 建造者模式
2、基本介绍
- 1)建造者模式(Builder Pattern)又叫生成器模式,是一种对象构建模式。它可以将复杂对象的建造过程抽象出来(抽象类别),使这个抽象过程的不同实现方法可以构造出不同表现(属性)的对象
- 2)建造者模式是一步一步创建一个复杂的对象,它允许用户只通过指定复杂对象的类型和内容就可以构建它们,用户不需要知道内部的具体构建细节

3、建造者模式的四个角色
- 1)
Product(产品角色):一个具体的产品对象 - 2)
Builder(抽象建造者):可建一个 Product 对象的各个部件指定的接口 / 抽象类 - 3)
ConcreteBuilder(具体建造者):实现接口,构建和装配各个部件 - 4)
Director(指挥者):构建一个使用 Builder 接口的对象。它主要是用于创建一个复杂的对象。它主要有两个作用- 一是隔离了客户与对象的生产过程
- 二是负责控制产品对象的生产过程
4、建造者模式原理类图

5、建造者模式解决盖房需求
需要建房子:这一过程为打桩、砌墙、封顶。不管是普通房子也好,别墅也好都需要经历这些过程,下面我们使用建造者模式(Builder Pattern)来完成
UML 类图

//产品角色
public class House {private String pile;private String wall;private String roof;public String getPile() {return pile;}public void setPile(String pile) {this.pile = pile;}public String getWall() {return wall;}public void setWall(String wall) {this.wall = wall;}public String getRoof() {return roof;}public void setRoof(String roof) {this.roof = roof;}
}
//抽象建造者
public abstract class HouseBuilder {private House house = new House();public abstract void piling();public abstract void walling();public abstract void capping();public House build() {return house;}
}
//具体建造者1
public class NormalRoomBuilder extends HouseBuilder {@Overridepublic void piling() {System.out.println("普通房打桩...");}@Overridepublic void walling() {System.out.println("普通房砌墙...");}@Overridepublic void capping() {System.out.println("普通房封顶...");}
}
//具体建造者2
public class HighRiseBuilder extends HouseBuilder {@Overridepublic void piling() {System.out.println("高楼打桩...");}@Overridepublic void walling() {System.out.println("高楼砌墙...");}@Overridepublic void capping() {System.out.println("高楼封顶...");}
}
//具体建造者3
public class VillaBuilder extends HouseBuilder {@Overridepublic void piling() {System.out.println("别墅打桩...");}@Overridepublic void walling() {System.out.println("别墅砌墙...");}@Overridepublic void capping() {System.out.println("别墅封顶...");}
}
//指挥者
public class HouseDirector {private HouseBuilder houseBuilder;public HouseDirector() {}public void setHouseBuilder(HouseBuilder houseBuilder) {this.houseBuilder = houseBuilder;}public House buildHouse() {houseBuilder.piling();houseBuilder.walling();houseBuilder.capping();return houseBuilder.build();}
}public class BuilderTest {public static void main(String[] args) {HouseDirector houseDirector = new HouseDirector();House house;houseDirector.setHouseBuilder(new NormalRoomBuilder());house = houseDirector.buildHouse();houseDirector.setHouseBuilder(new HighRiseBuilder());house = houseDirector.buildHouse();houseDirector.setHouseBuilder(new VillaBuilder());house = houseDirector.buildHouse();}
}
6、JDK 源码分析
java.lang.StringBuilder 中的建造者模式



角色分析
Appendable接口定义了多个append方法(抽象方法),即Appendable为抽象建造者,定义了抽象方法AbstractStringBuilder实现了Appendable接口方法,这里的AbstractStringBuilder已经是建造者,只是不能实例化StringBuilder既充当了指挥者角色,又充当了具体的建造者,建造方法的实现是由AbstractStringBuilder完成,StringBuilder继承了AbstractStringBuilder
7、注意事项及细节
- 1)客户端(使用程序)不必知道产品内部组成的细节,将产品本身与产品的创建过程解耦,使得相同的创建过程可以创建不同的产品对象
- 2)每一个具体建造者都相对独立,而与其他的具体建造者无关,因此可以很方便地替换具体建造者或增加新的具体建造者,用户使用不同的具体建造者即可得到不同的产品对象
- 3)可以更加精细地控制产品的创建过程。将复杂产品的创建步骤分解在不同的方法中,使得创建过程更加清晰,也更方便使用程序来控制创建过程
- 4)增加新的具体建造者无须修改原有类库的代码,指挥者类针对抽象建造者类编程,系统扩展方便,符合“开闭原则”
- 5)建造者模式所创建的产品一般具有较多的共同点,其组成部分相似,如果产品之间的差异性很大,则不适合使用建造者模式,因此其使用范围受到一定的限制
- 6)如果产品的内部变化复杂,可能会导致需要定义很多具体建造者类来实现这种变化,导致系统变得很庞大。因此在这种情况下,要考虑是否选择建造者模式
8、抽象工厂模式 VS 建造者模式
抽象工厂模式实现对产品家族的创建,一个产品家族是这样的一系列产品:具有不同分类维度的产品组合,采用抽象工厂模式不需要关心构建过程,只关心什么产品由什么工厂生产即可。
而建造者模式则是要求按照指定的蓝图建造产品,它的主要目的是通过组装零配件而产生一个新产品
相关文章:
设计模式-创建型-04-建造者模式
1、盖房项目需求 1)需要建房子:这一过程为打桩、砌墙、封顶2)房子有各种各样的,比如普通房,高楼,别墅,各种房子的过程虽然一样,但是要求不要相同的3)请编写程序…...
jenkins中配置参数化,并在python脚本接收参数实现参数化执行
在公司内进行Monkey测试脚本集成jenkins时,因为需要指定公司内不同的app进行测试。那么可以有两种方法解决该问题,要么创建多个脚本文件,多个jenkins jobs,进行构建。要么可以在配置job时通过传参数的方式,在python脚本…...
【SCAU数据挖掘】数据挖掘期末总复习题库应用题及解析
1. 给定圆的半径为e ,令 MinPts3,考虑下面两幅图。 (1)哪些对象是核心对象? m,p,o,r(因为这些核心对象在半径e的范围内都至少包含MinPts3个对象) (2)哪些对象是直接密度可达的? 对象q是…...
ADB->获取当前正在显示的Fragment和Activity的ADB命令
获取当前显示的Activity adb shell "dumpsys window | grep mCurrentFocus"指令拆解adb shell:启动一个远程shell来运行设备上的命令dumpsys window:获取当前窗口管理器的信息|:将前一个命令的输出作为后一个命令的输入grep mCurr…...
C#——集合List
list list集合和Arraylist基本一样,只不过list是C#2.0版本新加入的范型类型。list也可以通过索引操作里面的元素,也有对list进行增删改查 概念 Array静态数组 * Arraylist 动态数组 * list集合 * 1. Array是容量是固定的,但是ArrayList和…...
小程序-生命周期(2) 应用周期/页面周期
一.应用周期 应用周期指的是小程序:启动->运行->销毁的整个过程。 应用周期伴随一些函数来进行控制,这些函数卸载app.js里面的App方法里。 分别由onLaunch, onShow,onHide依次进行。 onLaunch:初始化的时候运行…...
什么是模板字符串?
模板字符串(Template Literals)是ES6(ECMAScript 2015)中引入的一种新的字符串表示方法,允许我们嵌入表达式,并在运行时将它们转换为字符串。模板字符串使用反引号()来定义ÿ…...
服务器数据恢复—热备盘未完全启用导致raid5阵列崩溃的数据恢复案例
服务器存储故障: 一台EMC某型号存储由于存储中raid5阵列出现故障导致服务器崩溃,由于数据涉密,需要工程师到现场恢复数据。 服务器数据恢复工程师到现场后对数据进行检测,经过检测发现服务器崩溃是由于raid中某些硬盘掉线所导致。…...
微服务项目雪崩的解决思路
雪崩的介绍 雪崩是微服务中某个服务挂了,无法返回请求,导致调用改服务的上层服务也故障,最终形成连锁反应,导致整个系统故障。 解决思路 一般有四种思路: 1.最简单的就是超时处理,即超过一段时间就返回…...
汇编语言程序设计 - 新建一个文件:d:\abc.txt,从键盘输入文件的内容(不超过100个字符)
80x86汇编习题 题目描述:编写一个程序,新建一个文件:d:\abc.txt,从键盘输入文件的内容(不超过100个字符) 思路: 1,定义好文件名,记得末尾0 2,定义好缓冲区…...
【Linux】进程间通信2——命名管道
1. 命名管道(FIFO) 1.1. 基本概念 简单,给匿名管道起个名字就变成了命名管道 那么如何给 匿名管道 起名字呢? 结合文件系统,给匿名管道这个纯纯的内存文件分配 inode,将文件名与之构建联系,关键点在于不给它分配 D…...
语音翻译软件app排名来啦,这些工具让旅游畅通无阻
#这个夏天我们一定要去看海# 出国旅行时,语言障碍常常是最让人头疼的问题之一。 特别是在像缅甸这样英语并不普及的国家,基本的日常交流,比如用餐或问路,都可能成为难题。 然而,随着技术的进步,现在有了…...
nginx脚本原理if指令实现详解
之前的文章我们探讨了nginx的变量,接着就是脚本原理,也就是复杂变量,理解了前面的实现原理,接下来了解if,break,return,set就要简单多。 指令有不少,没必要全部探讨,了解了其中之一…...
数据提取与治理:企业数字化转型的双引擎
在当今数字化浪潮中,企业正面临着前所未有的挑战和机遇。为了在这场变革中立于不败之地,数字化转型成为了企业不可或缺的战略选择。而在数字化转型的众多关键要素中,数据提取与治理技术无疑扮演着至关重要的角色,它们如同双引擎一…...
Java8 新特性 记录【持续更新】
目录 一、Stream 相关 1、findFirst 方法 二、Optional 1、如何构造Optional 2、ifPresent 方法 一、Stream 相关 1、findFirst 方法 Stream的findFirst方法在此流中查找第一个元素作为Optional。 如果流中没有元素,findFirst返回空的Optional。 如果流没…...
Protobuf详解及入门指南
Protobuf详解及入门指南 大家好,我是免费搭建查券返利机器人省钱赚佣金就用微赚淘客系统3.0的小编,也是冬天不穿秋裤,天冷也要风度的程序猿!在分布式系统和跨平台通信中,高效、轻量的序列化协议尤为重要。Google的Pro…...
[Java基本语法] 逻辑控制与方法
🌸个人主页:https://blog.csdn.net/2301_80050796?spm1000.2115.3001.5343 🏵️热门专栏:🍕 Collection与数据结构 (92平均质量分)https://blog.csdn.net/2301_80050796/category_12621348.html?spm1001.2014.3001.5482 🧀线程与…...
新手教学系列-基础知识(SSH使用)
基础知识(SSH使用) 什么是ssh Secure Shell(安全外壳协议,简称SSH)是一种加密的网络传输协议,可在不安全的网络中为网络服务提供安全的传输环境[1]。SSH通过在网络中创建安全隧道来实现SSH客户端与服务器之间的连接[2]。虽然任何网络服务都可以通过SSH实现安全传输,SS…...
如何通过细节处理,让展馆展示效果倍增?
如今,企业展览馆已经成为企业树立形象、产品推广的重要平台,他们利用当下流行的多媒体技术,精心设计出一个展览馆,不仅能够吸引观众的眼球,还能够让企业品牌形象更加突出,不过想要制作出一个优质的企业展览…...
汽车IVI中控开发入门及进阶(二十九):i.MX6
前言: i.MX 6双/6Quad处理器集成多媒体应用处理器,是不断增长的多媒体产品系列的一部分,提供高性能处理,并针对最低功耗进行了优化。 i.MX 6Dual/6Quad处理器采用先进的quad-ArmCortex-A9内核,运行速度高达800 MHz,包括2D和3D图形处理器、1080p视频处理和集成电源管理。…...
eNSP-Cloud(实现本地电脑与eNSP内设备之间通信)
说明: 想象一下,你正在用eNSP搭建一个虚拟的网络世界,里面有虚拟的路由器、交换机、电脑(PC)等等。这些设备都在你的电脑里面“运行”,它们之间可以互相通信,就像一个封闭的小王国。 但是&#…...
从WWDC看苹果产品发展的规律
WWDC 是苹果公司一年一度面向全球开发者的盛会,其主题演讲展现了苹果在产品设计、技术路线、用户体验和生态系统构建上的核心理念与演进脉络。我们借助 ChatGPT Deep Research 工具,对过去十年 WWDC 主题演讲内容进行了系统化分析,形成了这份…...
剑指offer20_链表中环的入口节点
链表中环的入口节点 给定一个链表,若其中包含环,则输出环的入口节点。 若其中不包含环,则输出null。 数据范围 节点 val 值取值范围 [ 1 , 1000 ] [1,1000] [1,1000]。 节点 val 值各不相同。 链表长度 [ 0 , 500 ] [0,500] [0,500]。 …...
什么是EULA和DPA
文章目录 EULA(End User License Agreement)DPA(Data Protection Agreement)一、定义与背景二、核心内容三、法律效力与责任四、实际应用与意义 EULA(End User License Agreement) 定义: EULA即…...
Matlab | matlab常用命令总结
常用命令 一、 基础操作与环境二、 矩阵与数组操作(核心)三、 绘图与可视化四、 编程与控制流五、 符号计算 (Symbolic Math Toolbox)六、 文件与数据 I/O七、 常用函数类别重要提示这是一份 MATLAB 常用命令和功能的总结,涵盖了基础操作、矩阵运算、绘图、编程和文件处理等…...
汇编常见指令
汇编常见指令 一、数据传送指令 指令功能示例说明MOV数据传送MOV EAX, 10将立即数 10 送入 EAXMOV [EBX], EAX将 EAX 值存入 EBX 指向的内存LEA加载有效地址LEA EAX, [EBX4]将 EBX4 的地址存入 EAX(不访问内存)XCHG交换数据XCHG EAX, EBX交换 EAX 和 EB…...
浅谈不同二分算法的查找情况
二分算法原理比较简单,但是实际的算法模板却有很多,这一切都源于二分查找问题中的复杂情况和二分算法的边界处理,以下是博主对一些二分算法查找的情况分析。 需要说明的是,以下二分算法都是基于有序序列为升序有序的情况…...
A2A JS SDK 完整教程:快速入门指南
目录 什么是 A2A JS SDK?A2A JS 安装与设置A2A JS 核心概念创建你的第一个 A2A JS 代理A2A JS 服务端开发A2A JS 客户端使用A2A JS 高级特性A2A JS 最佳实践A2A JS 故障排除 什么是 A2A JS SDK? A2A JS SDK 是一个专为 JavaScript/TypeScript 开发者设计的强大库ÿ…...
接口自动化测试:HttpRunner基础
相关文档 HttpRunner V3.x中文文档 HttpRunner 用户指南 使用HttpRunner 3.x实现接口自动化测试 HttpRunner介绍 HttpRunner 是一个开源的 API 测试工具,支持 HTTP(S)/HTTP2/WebSocket/RPC 等网络协议,涵盖接口测试、性能测试、数字体验监测等测试类型…...
Caliper 负载(Workload)详细解析
Caliper 负载(Workload)详细解析 负载(Workload)是 Caliper 性能测试的核心部分,它定义了测试期间要执行的具体合约调用行为和交易模式。下面我将全面深入地讲解负载的各个方面。 一、负载模块基本结构 一个典型的负载模块(如 workload.js)包含以下基本结构: use strict;/…...
