设计模式6——建造者模式(builder)

2023-05-16

1,盖房项目需求

盖房项目需求

1) 需要建房子:这一过程为打桩、砌墙、封顶

2) 房子有各种各样的,比如普通房,高楼,别墅,各种房子的过程虽然一样,但是要求不要相同的.

3) 请编写程序,完成需求.

传统方式解决盖房需求


public abstract class AbstractHouse {
    
    //打地基
    public abstract void buildBasic();
    //砌墙
    public abstract void buildWalls();
    //封顶
    public abstract void roofed();
    
    public void build() {
        buildBasic();
        buildWalls();
        roofed();
    }
    
}

传统方式解决盖房需求问题分析

1) 优点是比较好理解,简单易操作。

2) 设计的程序结构,过于简单,没有设计缓存层对象,程序的扩展和维护不好. 也就是说,这种设计方案,把产品(即:房子) 和 创建产品的过程(即:建房子流程) 封装在一起,耦合性增强了。

3) 解决方案:将产品和产品建造过程解耦 => 建造者模式.

 

2,建造者模式基本介绍

基本介绍

1) 建造者模式(Builder Pattern) 又叫生成器模式,是一种对象构建模式。它可以将复杂对象的建造过程抽象出来(抽象类别),使这个抽象过程的不同实现方法可以构造出不同表现(属性)的对象。

2) 建造者模式 是一步一步创建一个复杂的对象,它允许用户只通过指定复杂对象的类型和内容就可以构建它们,用户不需要知道内部的具体构建细节。

 

3,建造者模式的四个角色

1) Product(产品角色): 一个具体的产品对象。

2) Builder(抽象建造者): 创建一个Product对象的各个部件指定的 接口/抽象类。

3) ConcreteBuilder(具体建造者): 实现接口,构建和装配各个部件。

4) Director(指挥者): 构建一个使用Builder接口的对象。它主要是用于创建一个复杂的对象。它主要有两个作用,一是:隔离了客户与对象的生产过程,二是:负责控制产品对象的生产过程。

 

4,建造者模式原理类图

 

5,建造者模式解决盖房需求

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

2) 思路分析图解(类图)

3) 代码实现

先来看看director类:
//指挥者,这里去指定制作流程,返回产品
public class HouseDirector {
    
    HouseBuilder houseBuilder = null;

    //构造器传入 houseBuilder
    public HouseDirector(HouseBuilder houseBuilder) {
        this.houseBuilder = houseBuilder;
    }

    //通过setter 传入 houseBuilder
    public void setHouseBuilder(HouseBuilder houseBuilder) {
        this.houseBuilder = houseBuilder;
    }
    
    //如何处理建造房子的流程,交给指挥者
    public House constructHouse() {
        houseBuilder.buildBasic();
        houseBuilder.buildWalls();
        houseBuilder.roofed();
        return houseBuilder.buildHouse();
    }
}

也就是说director可以通过Builder类来实现创建的过程,director封装了实现的顺序。此外还有个产品类:
//产品->Product
public class House {
    private String baise;
    private String wall;
    private String roofed;
    public String getBaise() {
        return baise;
    }
    public void setBaise(String baise) {
        this.baise = baise;
    }
    public String getWall() {
        return wall;
    }
    public void setWall(String wall) {
        this.wall = wall;
    }
    public String getRoofed() {
        return roofed;
    }
    public void setRoofed(String roofed) {
        this.roofed = roofed;
    }
    
}
我认为建造者模式的好处在于将指挥者、建造者和产品进行了解耦,建造的顺序在指挥者哪里,实际的建造细节在建造者那里,建造的结果在产品里,这样的好处无疑是简化逻辑,并且方便扩展新的建造者。

 

6,在JDK中,StringBuilder的使用

 

StringBuilder在创建对象时,实际上调用了父类AbstractStringBuilder的方法:

public StringBuilder(CharSequence var1) {

this(var1.length() + 16);

this.append(var1);

}

 

public StringBuilder append(String var1) {

super.append(var1);

return this;

}

 

AbstractStringBuilder中append方法:

public AbstractStringBuilder append(String str) {

if (str == null)

return appendNull();

int len = str.length();

ensureCapacityInternal(count + len);

str.getChars(0, len, value, count);

count += len;

return this;

}

 

实际上就是给AbstractStringBuilder的char[]数组添加字符串,首先判断是否为空,然后保证value数组能够装的下来,然后把扩充数组。

 

建造者模式在JDK的应用和源码分析

 

3) 源码中建造者模式角色分析

Appendable 接口定义了多个append方法(抽象方法), 即Appendable 为抽象建造者, 定义了抽象方法

 

AbstractStringBuilder 实现了 Appendable 接口方法,这里的AbstractStringBuilder 已经是建造者,只是不能实例化

 

StringBuilder 即充当了指挥者角色,同时充当了具体的建造者, 建造方法的实现是由 AbstractStringBuilder 完成, 而StringBuilder 继承了AbstractStringBuilder

 

7,建造者模式的注意事项和细节

 

1) 客户端(使用程序)不必知道产品内部组成的细节,将产品本身与产品的创建过程解耦,使得相同的创建过程可以创建不同的产品对象

2) 每一个具体建造者都相对独立,而与其他的具体建造者无关,因此可以很方便地替换具体建造者或增加新的具体建造者, 用户使用不同的具体建造者即可得到不同的产品对象

3) 可以更加精细地控制产品的创建过程 。将复杂产品的创建步骤分解在不同的方法中,使得创建过程更加清晰,也更方便使用程序来控制创建过程

4) 增加新的具体建造者无须修改原有类库的代码,指挥者类针对抽象建造者类编程,系统扩展方便,符合 “开闭原则”

5) 建造者模式所创建的产品一般具有较多的共同点,其组成部分相似, 如果产品之间的差异性很大,则不适合使用建造者模式,因此其使用范围受到一定的限制。

6) 如果产品的内部变化复杂,可能会导致需要定义很多具体建造者类来实现这种变化,导致系统变得很庞大, 因此在这种情况下,要考虑是否选择建造者模式.

7) 抽象工厂模式VS建造者模式

抽象工厂模式实现对产品家族的创建,一个产品家族是这样的一系列产品:具有不同分类维度的产品组合,采用抽象工厂模式不需要关心构建过程,只关心什么产品由什么工厂生产即可。而建造者模式则是要求按照指定的蓝图建造产品,它的主要目的是通过组装零配件而产生一个新产品

 

 

 

本文内容由网友自发贡献,版权归原作者所有,本站不承担相应法律责任。如您发现有涉嫌抄袭侵权的内容,请联系:hwhale#tublm.com(使用前将#替换为@)

设计模式6——建造者模式(builder) 的相关文章

  • 十大 Python GUI 框架比较

    图形用户界面 GUI 是任何 Web 应用程序中最重要的部分之一 有人会说最重要的部分 xff0c 因为今天的老练用户很快就会放弃可用性差的应用程序 Python 应用程序也是如此 新手 Python 程序员在掌握了 Python 编程的基
  • 如何用ps将图片修改成指定大小

    这篇文章主要介绍如何用ps将图片修改成指定大小 xff1a 一 按原像素比例 修改图片的尺寸 1 先来看看它原来的尺寸 xff0c 如图所示 500X481px 2 首先用ps将图片文件打开 xff0c 使用ps菜单命令 xff1a lt
  • docker 安装rabbitMQ(最详细)

    docker 安装rabbitMQ 1 rabbitMQ介绍 RabbitMQ是一套开源 xff08 MPL xff09 的消息队列服务软件 xff0c 是由 LShift 提供的一个 Advanced Message Queuing Pr
  • 阿里云-ECS云服务器跨地域部署k8s集群

    阿里云 ECS云服务器跨地域部署k8s集群 一 背景介绍二 环境准备2 1 ECS云服务资源清单2 2 K8s软件列表 三 阿里云ECS服务器网络问题3 1 问题阐述3 2 解决方案 四 服务节点调整 xff08 master xff0c
  • 代码命名规范是一种责任也是一种精神(工匠精神)

    代码命名规范之美 规范概述命名规范管理类命名BootstrapProcessorManagerHolderFactoryProviderRegistrarEngineServiceTask 传播类命名ContextPropagator 回调
  • Kubernetes集群搭建(高可用)附全自动脚本

    高可用Kubernetes集群搭建 一 前言介绍 1 1 重要概念 二 系统架构 2 1 架构基本需求 2 2 架构图 三 环境准备 3 1 云服务或虚拟机清单 3 2 网络配置 针对使用vmware虚拟机用户需要操作 3 3 虚拟机网络设
  • k8s 集群部署ingress-nginx

    k8s 集群部署ingress nginx 环境准备 helm方式安装ingress nginx master边缘节点 创建命名空间和部署ingress 第一个ingress 例子 查看ingress controller配置 其实就是对应
  • k8s 集群部署traefik

    k8s 集群部署traefik k8s 集群部署traefik 环境准备 下载traefik helm方式安装traefik master边缘节点 执行安装 查看安装结果 安装traefik dashboard dashboard安装和查看
  • Linux系统(Centos)安装tomcat和部署Web项目

    文章结构 1 准备工作 2 在Linux下安装Tomcat8 0 3 Linux中配置tomcat的服务器启动和关闭和配置tomcat的开机启动 4 给tomcat配置用户名和密码登录 5 使用IDEA打包Maven托管的WEB项目 6 将
  • 如何判断蓝牙设备类型

    我们在开发Android的蓝牙应用时 xff0c 可能需要知道扫描到的蓝牙设备是什么类型 xff0c 然后过滤掉不符合要求的设备 xff0c 只保留符合要求的设备 xff0c 例如我们在车载系统上开发蓝牙电话应用时 xff0c 我们希望只显
  • Aspose.Words for Java 体验

    公司中要做一些导出word的工作 xff0c 经别人推荐 xff0c 使用了Aspose Words for Java xff0c 感觉很好用 xff0c 美中不足的地方就是 xff0c 它是收费软件 原理吗 xff1f 比较常规 xff0
  • 汽车制造行业OEM Tier1 Tier2指代什么?

    OEM OEM是Original Equipment Manufacturer的缩写 xff0c 通常指设备厂商 主机厂 整车厂 例如 xff1a 宝马 奔驰 奥迪 大众 丰田 国内汽车主机厂排名前十分别是上汽集团 东风汽车 北京汽车 长安
  • Android应用系统签名方法

    1 应用配置sharedUserId 在AndroidManifest xml文件根节点中加入属性 xff1a android sharedUserId 61 34 android uid system 34 2 找到系统签名文件 plat
  • Android 读取CPU/GPU运行参数(MTK平台)

    一 使用场景 Android运行一段世时间后 xff0c 系统出现卡顿 二 分析 amp 定位问题 系统卡顿 xff0c 同时又发现芯片温度很高 xff0c 怀疑是温度过高导致CPU降频 xff0c 因此我们要将一段时间内CPU的运行信息打
  • Android签名 (二) 制作签名文件

    你可能想知道 通过这篇博客可以解决哪些问题以及学到什么 xff1a 1 公司开发一个新的app xff0c 如何创建一个应用签名 xff1f 2 为了安全性 xff0c Android系统不想使用Google给的原生签名 xff0c 如何定
  • Android签名 (一) 查看签名信息

    你可能想知道 通过这篇博客可以解决哪些问题以及学到什么 xff1a 1 如果我们有一个应用 xff0c 如何查看应用的签名信息 xff1f 2 如果我们有签名原始文件 xff0c 如何查看签名文件中的签名信息 xff1f 这篇博客介绍了如何
  • L8 U3 职业生涯

    Module 1 谈论你最近的工作 1 描述工作 描述工作的形容词 让我们来看一下可以用来描述工作 xff0c 项目和客户的形容词 用enjoyable 和 engaging来描述你觉得有意思的工作或者项目 For me sales is
  • L8 U4 商务旅行

    Module 1 计划商务旅行 1 处理信息 You mean with Lindstrom 你是说和林特罗姆 xff1f Yes with Lindstrom 是的 xff0c 和林特罗姆 Exactly 完全正确 You mean yo
  • L8 U5 产品和创新

    Module 1 产品特点 1 产品特点 询问产品特性 在询问商店中的产品时 xff0c 您可能首先想询问其质量水平 top of the range 高档的middle of the range 中档的good value for mon
  • Android打包jar的两种方法

    方法一 xff1a 使用Android Studio打包 方法二 xff1a 使用Android Build System打包 一 Android Studio打包 1 新建Android Library xff0c 取名为opensdk

随机推荐

  • LCS 下载插件

    难度简单2收藏分享切换为英文接收动态反馈 小扣打算给自己的 VS code 安装使用插件 xff0c 初始状态下带宽每分钟可以完成 1 个插件的下载 假定每分钟选择以下两种策略之一 使用当前带宽下载插件将带宽加倍 xff08 下载插件数量随
  • 调用webservice异常总结

    发布和调用Webservice很简单 xff0c 但小问题依然不断 xff0c 特总结如下 xff1a 一 Java调用 net的webService产生 服务器未能识别 HTTP 标头 SOAPAction 的值 错误 解决方案 xff1
  • 去除Evaluation Warning : The document was created with Spire.PDF for Java.

    去除Evaluation Warning The document was created with Spire PDF for Java 最近项目中有一个需求需要把PDF文件添加页码 xff0c 最终在网上找到了用Spire去添加的方法
  • 第二章 简单网页的爬取与Xpath、Json使用 2021-09-09

    爬虫系列总目录 本章节介绍爬虫中使用的基础库用于选择 xff0c 过滤页面信息 包括requests xff0c bs4 xff0c xpath xff0c 正则表达式re xff0c json 等内容 xff0c 能够实现对简单页面的获取
  • 解决crontab定时任务多次执行

    今天使用linux crontab定时任务时 xff0c 可能由于配置不妥 xff0c 任务多执行一次 xff0c 如下是我程序的日志记录 xff08 执行了两次 xff0c 我设置的是每分钟执行1次 xff09 解决如下 重启cronta
  • ruoyi对接CAS统一身份认证

    暂定逻辑如下 xff1a 搭建CAS服务器端 xff1a 项目地址 xff1a https gitee com weigang wu cas server webapp git 项目里有二开的说明文档 xff0c 如 xff1a 按照自定义
  • Linux 系统启动过程

    简介 Linux 系统启动过程大致分为5个阶段 xff1a 1 内核的引导 2 运行 init 3 系统初始化 4 建立终端 5 用户登录系统 内核引导 计算机通电后 xff0c 首先会进行 BIOS 开机自检 xff0c 然后根据BIOS
  • Ubuntu 修改$PS1 自定义命令提示符

    文章更新于 xff1a 2020 03 25 文章目录 一 自定义命令提示符1 可修改的是那部分 xff1f 2 修改 PS1 变量3 PS1 变量格式4 如何修改背景颜色5 修改字体 二 Enjoy xff01 一 自定义命令提示符 1
  • C#byte类型

    byte类型的范围是0 255 转换为二进制是00000000 11111111 C 中对byte类型的处理还是很特殊的 下面用几行简单的代码来说明问题 byte x 61 1 byte y 61 2 byte z 61 x 43 y er
  • JVM内存分配机制详解

    目录 1 对象创建流程 TODO 1 1 jvm分配内存 1 2 设置对象头 1 2 1 对象头实例 1 2 2 指针压缩 2 JVM对象内存分配 2 1 逃逸分析和标量替换 2 1 1 逃逸分析和标量替换实战 2 2 eden区分配内存过
  • 【已解决】Windows10安装报:Windows检测到EFI系统分区格式化为NIFS,将EFI系统分区格式化为FAT32,然后重新启动安装

    手动擦除驱动器并将其转换为 GPT 关闭电脑 xff0c 然后放入 Windows 安装 DVD 或 USB 密钥 在 UEFI 模式下将电脑启动到 DVD 或 USB 密钥 有关详细信息 xff0c 请参阅 启动到 UEFI 模式或传统
  • SpringBoot系列之【启动流程详解】

    文章目录 前言一 SpringBoot特点二 SpringBoot启动流程图三 SpringBoot启动类入口1 注解 xff1a 64 SpringBootApplication 64 SpringBootConfiguration 64
  • word文档转html利器

    有需求 xff0c 就会有相应的技术出现 xff0c 以前知道word可以用来书写html网页 xff0c 那自然就可以转成html页面 xff0c 难道我们要用word开发html页面吗 xff1f 你可能会问 xff0c 我为什么要把w
  • Windows Terminal - 好物分享,真香~

    微情景 xff1a x1f482 xff1a 咦 xff0c 你的windows电脑还在使用默认的PowerShell cmd呀 xff1f x1f64b xff1a 对啊 x1f482 xff1a 你不觉得它们很丑又不好用吗 xff1f
  • oh-my-zsh - Linux/Git Bash个性化工具 - 好物分享,真香~

    一 什么是oh my zsh oh my zsh 是一个开源的zsh配置工具 xff0c 正如它主页上说的 xff0c oh my zsh基于zsh命令行 xff0c 提供了主题配置 xff0c 插件机制 xff0c 内置的便捷操作 让我们
  • python+Appium实现手机移动端自动化 - 模拟器 或 真机【有线】

    有线连接真机 xff0c 实现真机自动化 xff1f 实现模拟器自动化 xff1f 在这里 xff0c 都能满足你的需求 xff01 什么都不说了 xff0c 直接上干货吧 xff0c 亲测可用哦 x1f447 一 环境准备 首先 xff0
  • Linux 在终端中打开新的终端:gnome-terminal

    原文 xff1a gnome terminal技巧 xff08 1 xff09 Ubuntu中在桌面按下ctrl 43 alt 43 t即可打开终端 xff0c 这时候会进入用户的主目录 xff08 2 xff09 在一个终端中输入gnom
  • 微信公众号爬虫

    GitHub bowenpay wechat spider 微信公众号爬虫 https github com bowenpay wechat spider 虚拟机VMware下CentOS6 6安装教程图文详解 Linux教程 Linux公
  • win10你没有权限在此位置中保存文件

    首先进入Win10系统的hosts文件所在位置 xff0c 我们直接输入C Windows System32 Drivers etc后回车就可以打开了 xff0c 右键hosts文件 xff0c 选择属性 xff0c 如下图所示 点击hos
  • 设计模式6——建造者模式(builder)

    1 xff0c 盖房项目需求 盖房项目需求 1 需要建房子 xff1a 这一过程为打桩 砌墙 封顶 2 房子有各种各样的 xff0c 比如普通房 xff0c 高楼 xff0c 别墅 xff0c 各种房子的过程虽然一样 xff0c 但是要求不