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

面向对象设计模式:创建型模式之建造者模式

一、引入

在这里插入图片描述

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(…)
  • 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&#xff1a;建造和构建具有建筑结构的大型物体 建楼&#xff1a;打牢地基、搭建框架、然后自下而上一层层盖起来。构建物体&#xff1a;通常需要先建造组成这个物体的各个部分&#xff0c;然后分阶段把它们组装起来 二、建造者模式 2.1 Intent 意图 Separate…...

集成学习boosting、bagging、stacking

目录 一、介绍 二、三种架构学习 &#xff08;1&#xff09;boosting &#xff08;2&#xff09;bagging &#xff08;3&#xff09;stacking 一、介绍&#xff1a; 对于单个模型来说很难拟合复杂的数&#xff0c;模型的抗干扰能力较低&#xff0c;所以我们希望可以集成多…...

数据模型(上):模型分类和模型组成

1.模型分类 ​ 数据模型是一种由符号、文本组成的集合,用以准确表达信息景观,达到有效交流、沟通的目的。数据建模者要求能与来自不同部门,具有不同技术背景,不同业务经验,不同技术水平的人员交流、沟通。数据建模者要了解每个人员的观点,并通过反馈证明理解无误,最终作…...

郑州轻工业大学2022-2023(2) 数据结构题目集 - ZZULI

6-1 线性表元素的区间删除 6-1 线性表元素的区间删除 分数 20 全屏浏览题目 切换布局 作者 DS课程组 单位 浙江大学 给定一个顺序存储的线性表&#xff0c;请设计一个函数删除所有值大于min而且小于max的元素。删除后表中剩余元素保持顺序存储&#xff0c;并且相对位置不能改变…...

【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” 语句来删除已有的表&#xff1a; 实例 删除 “customers” 表&#xff1a; import…...

2023美团面试真题

面试前需要准备&#xff1a; 1. Java 八股文&#xff1a;了解常考的题型和回答思路&#xff1b; 2. 算法&#xff1a;刷 100-200 道题&#xff0c;记住刷题最重要的是要理解其思想&#xff0c;不要死记硬背&#xff0c;碰上原题很难&#xff0c;但 大多数的解题思路是相通的…...

【微信小程序开发全流程】篇章0:基于JavaScript开发的校园综合类微信小程序的概览

基于JavaScript开发的校园综合类微信小程序的概览 本文仅供学习&#xff0c;未经同意请勿转载 一些说明&#xff1a;上述项目来源于笔者我本科大三阶段2019年电子设计课程项目&#xff0c;在这个项目中&#xff0c;我主要是负责的部分有前端&#xff0c;前后端的对接&#xf…...

如何分析sql性能

1、前言 提到sql性能分析&#xff0c;可能都会想到explain&#xff0c;它在mysql里被称为执行计划&#xff0c;也就是说可以通过该命令看出mysql在通过优化器分析之后如何执行sql。mysql的内置优化器十分强大&#xff0c;它能帮我们把sql再次优化&#xff0c;以最低的成本去执…...

市场营销书籍推荐:《经理人参阅:市场营销》

要学好市场营销有什么好方法&#xff1f;答案是看书&#xff01;比起碎片化地去阅读一些文章或看一些相关视频&#xff0c;读书来得更实在些。倘若能静下心来好好读上一本系统性的市场营销书籍&#xff0c;学好营销管理将不会再是一件难事。然而&#xff0c;问题的关键是&#…...

WPF 控件专题 MediaElement控件详解

1、MediaElement 介绍 MediaElement&#xff1a;表示包含音频和/或视频的控件。 MediaOpened在引发事件之前&#xff0c;ActualWidth控件将ActualHeight报告为零&#xff0c;因为媒体内容用于确定控件的最终大小和位置。 对于仅音频内容&#xff0c;这些属性始终为零。 对于固…...

基于SpringBoot+SpringCloud+Vue前后端分离项目实战 --开篇

本文目录前言做项目的三大好处强强联手(天狗组合)专栏作者简介专栏的优势后端规划1. SpringBoot 和 SpringCloud 的选择2. Mybatis 和 MybatisPlus 和 JPA 的选择3. MySQL 和 Mongodb 的选择4. Redis 和 RocketMQ5. 后端规划小总结后端大纲提前掌握的知识点一期SpringBoot二期S…...

循环队列的实现

我们知道队列的实现可以用单链表和数组&#xff0c;但是循环链表也可以使用这两种方式。首先我们来看看单链表&#xff1a;首先使用单链表&#xff0c;我们需要考虑循环队列的一些特点。单链表实现循环队列我们要考虑几个核心问题&#xff1a;首先我们要区别 解决 空 和 满 的问…...

MTK平台开发入门到精通(休眠唤醒篇)休眠唤醒LPM框架

文章目录 一、lpm驱动源码分析二、设备属性调试文件沉淀、分享、成长,让自己和他人都能有所收获!😄 📢本篇文章将介绍 lpm 驱动源码分析。 mtk 平台下,其默认的 lpm 机制的源码位置:drivers/misc/mediatek/lpm/ 一、lpm驱动源码分析 目录:drivers/misc/mediatek/lpm/…...

ThreadLocal详解

一、ThreadLocal简介 1、简介 ThreadLocal叫做线程变量&#xff0c;它是一个线程的本地变量&#xff0c;意味着这个变量是线程独有的&#xff0c;是不能与其他线程共享的。这样就可以避免资源竞争带来的多线程的问题。 即 ThreadLocal类用来提供线程内部的局部变量&#xff0…...

利用Cookie劫持+HTML注入进行钓鱼攻击

目录 HTML注入和cookie劫持&#xff1a; 发现漏洞 实际利用 来源 HTML注入和cookie劫持&#xff1a; HTML注入漏洞一般是由于在用户能够控制的输入点上&#xff0c;由于缺乏安全过滤&#xff0c;导致攻击者能将任意HTML代码注入网页。此类漏洞可能会引起许多后续攻击&#…...

【接口汇总】常用免费的API

短信API 短信验证码&#xff1a;可用于登录、注册、找回密码、支付认证等等应用场景。支持三大运营商&#xff0c;3秒可达&#xff0c;99.99&#xff05;到达率&#xff0c;支持大容量高并发。 通知短信&#xff1a;当您需要快速通知用户时&#xff0c;通知短信是最快捷有效的…...

数字信号处理知识点

数字信号处理知识点1 频谱图中&#xff0c;横坐标取值范围的含义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…...

计算机网络第八版——第三章课后题答案(超详细)

第三章 该答案为博主在网络上整理&#xff0c;排版不易&#xff0c;希望大家多多点赞支持。后续将会持续更新&#xff08;可以给博主点个关注~ 第一章 答案 第二章 答案 【3-01】数据链路&#xff08;即逻辑链路&#xff09;与链路&#xff08;即物理链路&#xff09;有何区…...

九龙证券|磷酸亚铁锂是什么?磷酸亚铁锂的特点和性能介绍

磷酸亚铁锂是一种新式锂离子电池电极资料&#xff0c;化学式&#xff1a;LiFePO4&#xff0c;磷酸亚铁锂为近来新开发的锂离子电池电极资料&#xff0c;首要用于动力锂离子电池&#xff0c;作为正极活性物质运用&#xff0c;人们习气也称其为磷酸铁锂。 磷酸亚铁锂的特色和功能…...

3D目标检测(二)—— 直接处理点云的3D目标检测网络VoteNet、H3DNet

前言上次介绍了基于Point-Based方法处理点云的模块&#xff0c;3D目标检测&#xff08;一&#xff09;—— 基于Point-Based方法的PointNet点云处理系列,其中相关的模块则是构成本次要介绍的&#xff0c;直接在点云的基础上进行3D目标检测网络的基础。VoteNet对于直接在点云上预…...

手游刚开服就被攻击怎么办?如何防御DDoS?

开服初期是手游最脆弱的阶段&#xff0c;极易成为DDoS攻击的目标。一旦遭遇攻击&#xff0c;可能导致服务器瘫痪、玩家流失&#xff0c;甚至造成巨大经济损失。本文为开发者提供一套简洁有效的应急与防御方案&#xff0c;帮助快速应对并构建长期防护体系。 一、遭遇攻击的紧急应…...

多模态2025:技术路线“神仙打架”,视频生成冲上云霄

文&#xff5c;魏琳华 编&#xff5c;王一粟 一场大会&#xff0c;聚集了中国多模态大模型的“半壁江山”。 智源大会2025为期两天的论坛中&#xff0c;汇集了学界、创业公司和大厂等三方的热门选手&#xff0c;关于多模态的集中讨论达到了前所未有的热度。其中&#xff0c;…...

椭圆曲线密码学(ECC)

一、ECC算法概述 椭圆曲线密码学&#xff08;Elliptic Curve Cryptography&#xff09;是基于椭圆曲线数学理论的公钥密码系统&#xff0c;由Neal Koblitz和Victor Miller在1985年独立提出。相比RSA&#xff0c;ECC在相同安全强度下密钥更短&#xff08;256位ECC ≈ 3072位RSA…...

React Native 开发环境搭建(全平台详解)

React Native 开发环境搭建&#xff08;全平台详解&#xff09; 在开始使用 React Native 开发移动应用之前&#xff0c;正确设置开发环境是至关重要的一步。本文将为你提供一份全面的指南&#xff0c;涵盖 macOS 和 Windows 平台的配置步骤&#xff0c;如何在 Android 和 iOS…...

IGP(Interior Gateway Protocol,内部网关协议)

IGP&#xff08;Interior Gateway Protocol&#xff0c;内部网关协议&#xff09; 是一种用于在一个自治系统&#xff08;AS&#xff09;内部传递路由信息的路由协议&#xff0c;主要用于在一个组织或机构的内部网络中决定数据包的最佳路径。与用于自治系统之间通信的 EGP&…...

服务器硬防的应用场景都有哪些?

服务器硬防是指一种通过硬件设备层面的安全措施来防御服务器系统受到网络攻击的方式&#xff0c;避免服务器受到各种恶意攻击和网络威胁&#xff0c;那么&#xff0c;服务器硬防通常都会应用在哪些场景当中呢&#xff1f; 硬防服务器中一般会配备入侵检测系统和预防系统&#x…...

重启Eureka集群中的节点,对已经注册的服务有什么影响

先看答案&#xff0c;如果正确地操作&#xff0c;重启Eureka集群中的节点&#xff0c;对已经注册的服务影响非常小&#xff0c;甚至可以做到无感知。 但如果操作不当&#xff0c;可能会引发短暂的服务发现问题。 下面我们从Eureka的核心工作原理来详细分析这个问题。 Eureka的…...

AI病理诊断七剑下天山,医疗未来触手可及

一、病理诊断困局&#xff1a;刀尖上的医学艺术 1.1 金标准背后的隐痛 病理诊断被誉为"诊断的诊断"&#xff0c;医生需通过显微镜观察组织切片&#xff0c;在细胞迷宫中捕捉癌变信号。某省病理质控报告显示&#xff0c;基层医院误诊率达12%-15%&#xff0c;专家会诊…...

初探Service服务发现机制

1.Service简介 Service是将运行在一组Pod上的应用程序发布为网络服务的抽象方法。 主要功能&#xff1a;服务发现和负载均衡。 Service类型的包括ClusterIP类型、NodePort类型、LoadBalancer类型、ExternalName类型 2.Endpoints简介 Endpoints是一种Kubernetes资源&#xf…...

深度学习水论文:mamba+图像增强

&#x1f9c0;当前视觉领域对高效长序列建模需求激增&#xff0c;对Mamba图像增强这方向的研究自然也逐渐火热。原因在于其高效长程建模&#xff0c;以及动态计算优势&#xff0c;在图像质量提升和细节恢复方面有难以替代的作用。 &#x1f9c0;因此短时间内&#xff0c;就有不…...