面向对象设计模式:创建型模式之建造者模式
一、引入

Build:建造和构建具有建筑结构的大型物体
- 建楼:打牢地基、搭建框架、然后自下而上一层层盖起来。
- 构建物体:通常需要先建造组成这个物体的各个部分,然后分阶段把它们组装起来
二、建造者模式
2.1 Intent 意图
- Separate the construction of a complex object from its representation so that the same construction process can create different representations. 将复杂对象的构造与其表示分开,以便相同的构造过程可以创建不同的表示.
2.2 Applicability 适用性
- the algorithm for creating a complex object should be independent of the parts that make up the object and how they’re assembled. 创建复杂对象的算法应该独立于组成对象的部分以及它们的组装方式.
- 独立于:复杂对象的各个部分可能面临着剧烈的变化,但是将它们组合在一起的算法却相对稳定
- the construction process must allow different representations for the object that’s constructed. 构造过程必须允许所构造对象的不同表示.
(将变与不变分隔开)
2.3 类图

- Builder: specifies an abstract interface for creating parts of a Product object. 指定用于创建产品对象部件的抽象接口.
- ConcreteBuilder:
- Constructs and assembles parts of the product. 建造和组装产品的部分部件
- Defines and keeps track of the representation it creates. 定义并跟踪它所创建的表示
- Provides an interface (method) for retrieving the product. 提供了一个用于检索产品的接口(方法)
- Director: constructs an object using the Builder interface. 使用 Builder 接口构造一个对象
- Product: represents the complex object under construction. 表示正在构建的复杂对象
2.4 Collaborations 合作
- The client creates the Director object and configures it with the desired Builder object.
- new Director(new ConcreteBuilder())
- Director notifies the builder whenever a part of the product should be built. Director 会告知 builder 何时应创建产品的(哪个)部件
- constract()
- buildPart(A)
- buildPart(B)
- buildPart(…)
- constract()
- Builder handles requests from the director and adds parts to the product. Builder 处理 director 的请求,添加部件到产品
- The client retrieves the product from the builder. 客户端从 builder 取回产品.
2.5 建造者模式 VS 策略模式
- In Builder pattern, Director decides the calling sequence of the methods in Builder. 在构建器模式中,Director 决定 Builder 方法的调用顺序.
- In Template Method, the super class decides the calling sequence of the methods of subclass. 在模板方法中,超类决定子类的方法的调用顺序.
2.6 建造者模式实例:文档创建程序
- Builder
public abstract class Builder {public abstract void makeTitle(String title);public abstract void makeString(String str);public abstract void makeItems(String[] items);public abstract void close();
}
import java.io.*;public class HTMLBuilder extends Builder {private String filename; // 文件名private PrintWriter writer; // 用于编写文件的PrintWriterpublic void makeTitle(String title) { // HTML文件的标题filename = title + ".html"; // 将标题作为文件名try {writer = new PrintWriter(new FileWriter(filename)); // 生成 PrintWriter} catch (IOException e) {e.printStackTrace();}writer.println("<meta http-equiv=\"Content-Type\" content=\"text/html;charset=UTF-8\"/>\n");writer.println("<html><head><title>" + title + "</title></head><body>"); // 输出标题writer.println("<h1>" + title + "</h1>");}public void makeString(String str) { // HTML文件中的字符串writer.println("<p>" + str + "</p>"); // 用<p>标签输出}public void makeItems(String[] items) { // HTML文件中的条目writer.println("<ul>"); // 用<ul>和<li>输出for (int i = 0; i < items.length; i++) {writer.println("<li>" + items[i] + "</li>");}writer.println("</ul>");}public void close() { // 完成文档writer.println("</body></html>"); // 关闭标签writer.close(); // 关闭文件}public String getResult() { // 编写完成的文档return filename; // 返回文件名}
}
public class TextBuilder extends Builder {private String buffer = ""; // 文档内容保存在该字段中public void makeTitle(String title) { // 纯文本的标题buffer += "==============================\n"; // 装饰线buffer += "『" + title + "』\n"; // 为标题加上『』buffer += "\n"; // 换行}public void makeString(String str) { // 纯文本的字符串buffer += "- " + str + "\n"; // 为字符串添加buffer += "\n"; // 换行}public void makeItems(String[] items) { // 纯文本的条目for (int i = 0; i < items.length; i++) {buffer += " - " + items[i] + "\n"; // 为条目添加?}buffer += "\n"; // 换行}public void close() { // 完成文档buffer += "==============================\n"; // 装饰线}public String getResult() { // 完成后的文档return buffer;}
}
- Director
public class Director {private Builder builder;public Director(Builder builder) { // 因为接收的参数是Builder类的子类this.builder = builder; // 所以可以将其保存在builder字段中}public void construct() { // 编写文档builder.makeTitle("Greeting"); // 标题builder.makeString("从早上至下午"); // 字符串builder.makeItems(new String[]{ // 条目"早上好。","下午好。",});builder.makeString("晚上"); // 其他字符串builder.makeItems(new String[]{ // 其他条目"晚上好。","晚安。","再见。",});builder.close(); // 完成文档}
}
- Main Test:
public class Main {public static void main(String[] args) {if (args.length != 1) {usage();System.exit(0);}if (args[0].equals("plain")) {TextBuilder textbuilder = new TextBuilder();Director director = new Director(textbuilder);director.construct();String result = textbuilder.getResult();System.out.println(result);} else if (args[0].equals("html")) {HTMLBuilder htmlbuilder = new HTMLBuilder();Director director = new Director(htmlbuilder);director.construct();String filename = htmlbuilder.getResult();System.out.println(filename + "文件编写完成。");} else {usage();System.exit(0);}}public static void usage() {System.out.println("Usage: java Main plain 编写纯文本文档");System.out.println("Usage: java Main html 编写HTML文档");}
}


相关文章:
面向对象设计模式:创建型模式之建造者模式
一、引入 Build:建造和构建具有建筑结构的大型物体 建楼:打牢地基、搭建框架、然后自下而上一层层盖起来。构建物体:通常需要先建造组成这个物体的各个部分,然后分阶段把它们组装起来 二、建造者模式 2.1 Intent 意图 Separate…...
集成学习boosting、bagging、stacking
目录 一、介绍 二、三种架构学习 (1)boosting (2)bagging (3)stacking 一、介绍: 对于单个模型来说很难拟合复杂的数,模型的抗干扰能力较低,所以我们希望可以集成多…...
数据模型(上):模型分类和模型组成
1.模型分类 数据模型是一种由符号、文本组成的集合,用以准确表达信息景观,达到有效交流、沟通的目的。数据建模者要求能与来自不同部门,具有不同技术背景,不同业务经验,不同技术水平的人员交流、沟通。数据建模者要了解每个人员的观点,并通过反馈证明理解无误,最终作…...
郑州轻工业大学2022-2023(2) 数据结构题目集 - ZZULI
6-1 线性表元素的区间删除 6-1 线性表元素的区间删除 分数 20 全屏浏览题目 切换布局 作者 DS课程组 单位 浙江大学 给定一个顺序存储的线性表,请设计一个函数删除所有值大于min而且小于max的元素。删除后表中剩余元素保持顺序存储,并且相对位置不能改变…...
【Python语言基础】——Python MySQL Drop Table
Python语言基础——Python MySQL Drop Table 文章目录Python语言基础——Python MySQL Drop Table一、Python MySQL Drop Table一、Python MySQL Drop Table 删除表 您可以使用 “DROP TABLE” 语句来删除已有的表: 实例 删除 “customers” 表: import…...
2023美团面试真题
面试前需要准备: 1. Java 八股文:了解常考的题型和回答思路; 2. 算法:刷 100-200 道题,记住刷题最重要的是要理解其思想,不要死记硬背,碰上原题很难,但 大多数的解题思路是相通的…...
【微信小程序开发全流程】篇章0:基于JavaScript开发的校园综合类微信小程序的概览
基于JavaScript开发的校园综合类微信小程序的概览 本文仅供学习,未经同意请勿转载 一些说明:上述项目来源于笔者我本科大三阶段2019年电子设计课程项目,在这个项目中,我主要是负责的部分有前端,前后端的对接…...
如何分析sql性能
1、前言 提到sql性能分析,可能都会想到explain,它在mysql里被称为执行计划,也就是说可以通过该命令看出mysql在通过优化器分析之后如何执行sql。mysql的内置优化器十分强大,它能帮我们把sql再次优化,以最低的成本去执…...
市场营销书籍推荐:《经理人参阅:市场营销》
要学好市场营销有什么好方法?答案是看书!比起碎片化地去阅读一些文章或看一些相关视频,读书来得更实在些。倘若能静下心来好好读上一本系统性的市场营销书籍,学好营销管理将不会再是一件难事。然而,问题的关键是&#…...
WPF 控件专题 MediaElement控件详解
1、MediaElement 介绍 MediaElement:表示包含音频和/或视频的控件。 MediaOpened在引发事件之前,ActualWidth控件将ActualHeight报告为零,因为媒体内容用于确定控件的最终大小和位置。 对于仅音频内容,这些属性始终为零。 对于固…...
基于SpringBoot+SpringCloud+Vue前后端分离项目实战 --开篇
本文目录前言做项目的三大好处强强联手(天狗组合)专栏作者简介专栏的优势后端规划1. SpringBoot 和 SpringCloud 的选择2. Mybatis 和 MybatisPlus 和 JPA 的选择3. MySQL 和 Mongodb 的选择4. Redis 和 RocketMQ5. 后端规划小总结后端大纲提前掌握的知识点一期SpringBoot二期S…...
循环队列的实现
我们知道队列的实现可以用单链表和数组,但是循环链表也可以使用这两种方式。首先我们来看看单链表:首先使用单链表,我们需要考虑循环队列的一些特点。单链表实现循环队列我们要考虑几个核心问题:首先我们要区别 解决 空 和 满 的问…...
MTK平台开发入门到精通(休眠唤醒篇)休眠唤醒LPM框架
文章目录 一、lpm驱动源码分析二、设备属性调试文件沉淀、分享、成长,让自己和他人都能有所收获!😄 📢本篇文章将介绍 lpm 驱动源码分析。 mtk 平台下,其默认的 lpm 机制的源码位置:drivers/misc/mediatek/lpm/ 一、lpm驱动源码分析 目录:drivers/misc/mediatek/lpm/…...
ThreadLocal详解
一、ThreadLocal简介 1、简介 ThreadLocal叫做线程变量,它是一个线程的本地变量,意味着这个变量是线程独有的,是不能与其他线程共享的。这样就可以避免资源竞争带来的多线程的问题。 即 ThreadLocal类用来提供线程内部的局部变量࿰…...
利用Cookie劫持+HTML注入进行钓鱼攻击
目录 HTML注入和cookie劫持: 发现漏洞 实际利用 来源 HTML注入和cookie劫持: HTML注入漏洞一般是由于在用户能够控制的输入点上,由于缺乏安全过滤,导致攻击者能将任意HTML代码注入网页。此类漏洞可能会引起许多后续攻击&#…...
【接口汇总】常用免费的API
短信API 短信验证码:可用于登录、注册、找回密码、支付认证等等应用场景。支持三大运营商,3秒可达,99.99%到达率,支持大容量高并发。 通知短信:当您需要快速通知用户时,通知短信是最快捷有效的…...
数字信号处理知识点
数字信号处理知识点1 频谱图中,横坐标取值范围的含义2 MATLAB常用函数2.1 波形产生2.2 滤波器分析2.3 滤波器实现2.4 线性系统变换2.5 滤波器设计2.5.1 FIR滤波器2.5.2 IIR滤波器2.6 Transforms(变换)2.7 统计信号处理和谱分析2.8 Windows(窗函数)2.9 Parametric Mo…...
计算机网络第八版——第三章课后题答案(超详细)
第三章 该答案为博主在网络上整理,排版不易,希望大家多多点赞支持。后续将会持续更新(可以给博主点个关注~ 第一章 答案 第二章 答案 【3-01】数据链路(即逻辑链路)与链路(即物理链路)有何区…...
九龙证券|磷酸亚铁锂是什么?磷酸亚铁锂的特点和性能介绍
磷酸亚铁锂是一种新式锂离子电池电极资料,化学式:LiFePO4,磷酸亚铁锂为近来新开发的锂离子电池电极资料,首要用于动力锂离子电池,作为正极活性物质运用,人们习气也称其为磷酸铁锂。 磷酸亚铁锂的特色和功能…...
3D目标检测(二)—— 直接处理点云的3D目标检测网络VoteNet、H3DNet
前言上次介绍了基于Point-Based方法处理点云的模块,3D目标检测(一)—— 基于Point-Based方法的PointNet点云处理系列,其中相关的模块则是构成本次要介绍的,直接在点云的基础上进行3D目标检测网络的基础。VoteNet对于直接在点云上预…...
IDEA运行Tomcat出现乱码问题解决汇总
最近正值期末周,有很多同学在写期末Java web作业时,运行tomcat出现乱码问题,经过多次解决与研究,我做了如下整理: 原因: IDEA本身编码与tomcat的编码与Windows编码不同导致,Windows 系统控制台…...
Spark 之 入门讲解详细版(1)
1、简介 1.1 Spark简介 Spark是加州大学伯克利分校AMP实验室(Algorithms, Machines, and People Lab)开发通用内存并行计算框架。Spark在2013年6月进入Apache成为孵化项目,8个月后成为Apache顶级项目,速度之快足见过人之处&…...
理解 MCP 工作流:使用 Ollama 和 LangChain 构建本地 MCP 客户端
🌟 什么是 MCP? 模型控制协议 (MCP) 是一种创新的协议,旨在无缝连接 AI 模型与应用程序。 MCP 是一个开源协议,它标准化了我们的 LLM 应用程序连接所需工具和数据源并与之协作的方式。 可以把它想象成你的 AI 模型 和想要使用它…...
oracle与MySQL数据库之间数据同步的技术要点
Oracle与MySQL数据库之间的数据同步是一个涉及多个技术要点的复杂任务。由于Oracle和MySQL的架构差异,它们的数据同步要求既要保持数据的准确性和一致性,又要处理好性能问题。以下是一些主要的技术要点: 数据结构差异 数据类型差异ÿ…...
【Go】3、Go语言进阶与依赖管理
前言 本系列文章参考自稀土掘金上的 【字节内部课】公开课,做自我学习总结整理。 Go语言并发编程 Go语言原生支持并发编程,它的核心机制是 Goroutine 协程、Channel 通道,并基于CSP(Communicating Sequential Processes࿰…...
Mac软件卸载指南,简单易懂!
刚和Adobe分手,它却总在Library里给你写"回忆录"?卸载的Final Cut Pro像电子幽灵般阴魂不散?总是会有残留文件,别慌!这份Mac软件卸载指南,将用最硬核的方式教你"数字分手术"࿰…...
在鸿蒙HarmonyOS 5中使用DevEco Studio实现录音机应用
1. 项目配置与权限设置 1.1 配置module.json5 {"module": {"requestPermissions": [{"name": "ohos.permission.MICROPHONE","reason": "录音需要麦克风权限"},{"name": "ohos.permission.WRITE…...
uniapp中使用aixos 报错
问题: 在uniapp中使用aixos,运行后报如下错误: AxiosError: There is no suitable adapter to dispatch the request since : - adapter xhr is not supported by the environment - adapter http is not available in the build 解决方案&…...
【碎碎念】宝可梦 Mesh GO : 基于MESH网络的口袋妖怪 宝可梦GO游戏自组网系统
目录 游戏说明《宝可梦 Mesh GO》 —— 局域宝可梦探索Pokmon GO 类游戏核心理念应用场景Mesh 特性 宝可梦玩法融合设计游戏构想要素1. 地图探索(基于物理空间 广播范围)2. 野生宝可梦生成与广播3. 对战系统4. 道具与通信5. 延伸玩法 安全性设计 技术选…...
Web 架构之 CDN 加速原理与落地实践
文章目录 一、思维导图二、正文内容(一)CDN 基础概念1. 定义2. 组成部分 (二)CDN 加速原理1. 请求路由2. 内容缓存3. 内容更新 (三)CDN 落地实践1. 选择 CDN 服务商2. 配置 CDN3. 集成到 Web 架构 …...
