设计模式--建造者模式

news2024/12/24 8:43:25

项目需求

  盖房需求

  (1) 需要建房子:过程为 打地基 砌墙 封顶

  (2) 房子有高正各样的,比如 平房和高楼  建房子的过程虽然都一样 但是要求不要相同的细节

传统方式

public abstract class TraditionBuild {
    //打地基
    public abstract void foundation();

    //砌墙
    public abstract void wall();

    //封顶
    public abstract void capping();

    public void build(){
        foundation();
        wall();
        capping();
    }
}

public class TraditionBuildSon extends TraditionBuild{
    @Override
    public void foundation() {
        System.out.println("传统打地基");
    }

    @Override
    public void wall() {
        System.out.println("传统砌墙");
    }

    @Override
    public void capping() {
        System.out.println("传统封顶");
    }
}

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

(1) 容易理解 简单易操作

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

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

基本介绍

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

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

建造者模式的四个角色

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

(2) builder(抽象建造者): 创建一个product对象的各个部件指定的接口

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

(4) director(指挥者):构建一个使用builder接口的对象 它主要用于创建一个复杂的对象 它主要隔离了客户与对象的生产过程和负责控制产品对象的生产过程

代码演示

定义产品

  

@Data
//成品
public class House {
    //地基
    private String base;
    //砌墙
    private String wall;
    //封顶
    private String capping;
}

定义抽象建造者

//抽象建造者
public abstract class HouseBuilder {

    protected House house = new House();

    //定义建造流程 抽象方法

    public abstract void buildBase(); //打地基
    public abstract void buildWall(); //砌墙
    public abstract void buildCapping();//封顶

    /**
     * 建造房子总合
     */
    public House buildHouse(){
        return house;
    }

}

定义具体建造者

平房

public class CommonHouse extends HouseBuilder{
    @Override
    public void buildBase() {
        System.out.println("平房打地基5米");
    }

    @Override
    public void buildWall() {
        System.out.println("平房砌墙10天");
    }

    @Override
    public void buildCapping() {
        System.out.println("平房封顶");
    }

 高楼

public class HighHouse extends HouseBuilder{
    @Override
    public void buildBase() {
        System.out.println("高楼打地基15米");
    }

    @Override
    public void buildWall() {
        System.out.println("高楼砌墙30天");
    }

    @Override
    public void buildCapping() {
        System.out.println("高楼封顶");
    }

定义指挥者

public class HouseDirector {
    HouseBuilder houseBuilder = null;

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

    /**
     * set 传入
     */
    public void setHouseBuilder(HouseBuilder houseBuilder){
        this.houseBuilder = houseBuilder;
    }

    /**
     * 处理建造房子的流程 由指挥者处理
     */
    public House constructHouse(){
        houseBuilder.buildBase();
        houseBuilder.buildWall();
        houseBuilder.buildCapping();
        return houseBuilder.buildHouse();
    }
}

客户验收

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

StringBuilder就有应用建造者模式

进入源码查看 可以看到StringBuilder继承了AbstractStringBuilder

 进入AbstractStringBuilder查看,AbstractStringBuilder又实现了Appendable

 再进入Appendable查看

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

再回到AbstractStringBuilder

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

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

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

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

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

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

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

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

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

(7) 抽闲工厂模式vs建造者模式

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

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

如若内容造成侵权/违法违规/事实不符,请联系多彩编程网进行投诉反馈,一经查实,立即删除!

相关文章

Linux进程的fork、exit、wait等函数;区分父子进程;GDB调试多进程

Linux系统中进程可以创建子进程。 1. fork函数&#xff1a;创建新进程 #include<sys/types.h> #include<unistd.h>pid_t fork(void); /* 功能&#xff1a;一个进程创建新进程。原进程为父进程&#xff0c;新进程为子进程。 返回值&#xff1a;成功&#xff1a;子…

SuperMap iObjects Docker打包全攻略

SuperMap iObjects Docker打包全攻略 文章目录 SuperMap iObjects Docker打包全攻略说明开始打包iObjects容器启动容器参考 说明 此教程编写时使用的iObjects版本为 10.2.1 &#xff0c;理论高版本同样支持&#xff0c;具体自测。基础镜像为 Docker 官方 ubuntu:16.04完整版。…

C++ 类和对象(中)构造函数 和 析构函数

上篇链接&#xff1a;C 类和对象&#xff08;上&#xff09;_chihiro1122的博客-CSDN博客 类的6个默认成员函数 我们在C当中&#xff0c;在写一些函数的时候&#xff0c;比如在栈的例子&#xff1a; 如上述例子&#xff0c;用C 返回这个栈是否为空&#xff0c;直接返回的话&am…

基于OpenCV-python的图像增强和滤波

目录 彩色空间 直方图均衡化 图像滤波 梯度 一、彩色空间 OpenCV 的颜色空间主要有 BGR、HSV、Lab等&#xff0c;cvtColor 函数可以让图像在不同颜色空间转换。例如通过将花的图像转换到 HSV 颜色空间&#xff0c;在HSV空间内过滤出只含有花瓣颜色的像素&#xff0c;从而提…

公共资源包发布流程详解

文章目录 公有包发布并使用npm安装git仓库协议创建及使用 npm 私有包创建及使用 group npm 私有包私有仓账密存放位置 当公司各个系统都需要使用特定的业务模块时&#xff0c;这时候将代码抽离&#xff0c;发布到 npm 上&#xff0c;供下载安装使用&#xff0c;是个比较好的方案…

SQL Server基础 第七章 连接查询(内连接、表别名、左外连接、右外连接)

前言 连接查询是关系数据库中最主要的查询&#xff0c;主要包括内连接、外连接和交叉连接等。通过连接运算符可以实现多个表查询。前面章节的查询均是基于单表进行&#xff0c;但有时需要获取的信息存储于多张表中&#xff0c;此时就必须使用本章所介绍的多表连接查询技术来获取…

关于debug一晚上的一些思考,做开发到底要养成什么习惯?

总结&#xff1a;日志一定要写&#xff0c;日志一定要写&#xff0c;日志一定要写&#xff01; 今天晚上是我学开发过程中很不一样的一晚&#xff0c;今晚学到了很多。 虽然我也只是一个开发的初学小白&#xff0c;今天的debug分享是我的一个小方法和一个小记录&#xff0c;如…

第四章——数学知识2

欧拉函数 欧拉函数表示的是1-n中与n互质数的个数。 如1-6中&#xff1a;1&#xff0c;5都和6互质&#xff0c;因此互质数为2 欧拉函数分解质因数后表示为&#xff1a; 互质数个数可表示为 int main() {int n;cin >> n;while(n--){int a;cin >> a;//分解质因数int r…

TypeScript自学笔记

目录 1.什么是Ts? 1.1 设计公司&#xff1a;微软 1.2 TS概述 1.3 TS是静态类型 JS是动态类型 1.4 TS是强类型语言 JS是弱类型语言 2.TypeScript编译器 2.1 安装 2.2 TS自动编译和编译选项设置 3.TS的数据类型 3.1 基础数据类型number、string、boolean 3.2 Arrays&a…

大数据架构(二)大数据发展史

1.传统数仓发展史 传统数据仓库的发展史这里不展开架构细讲&#xff0c;只需快速过一遍即可。了解这个历史发展过程即可。 1.1 传统数仓历史 1.1.1 5个时代 传统数仓发展史可以称为5个时代的经典论证战。按照两位数据仓库大师 Ralph kilmball、Bill Innmon 在数据仓库建设理念上…

吃透Redis面试八股文

Redis连环40问&#xff0c;绝对够全&#xff01; Redis是什么&#xff1f; Redis&#xff08;Remote Dictionary Server&#xff09;是一个使用 C 语言编写的&#xff0c;高性能非关系型的键值对数据库。与传统数据库不同的是&#xff0c;Redis 的数据是存在内存中的&#xf…

Python Review 01

1、Anaconda Installation 使用Anaconda Navigator进行python环境管理&#xff0c;使用conda进行依赖管理。 2、Use of Jupyter 将代码写入一个个cell&#xff0c;代码文件由一个个cell组成&#xff0c;书写代码时就像一行一行在写笔记&#xff0c;这就是notebook的代码编辑环…

无宿主机权限情况下,获取pod的日志文件

如果没有宿主机权限,是无法访问宿主机及里边的文件的,但是如果想获取某些文件,如日志等如何操作呢? 整体思路:通过抓包工具,抓取websocket的的信息,然后把信息处理拼接后导出即可。 1、启动抓包工具 我这里使用的是charles抓包工具 2、打开对应pod的命令行窗口 3、抓…

基于灰度图像和小波图的双模态卷积神经网络在心血管疾病分类中的应用

目录 一、研究对象和ECG记录预处理 二、机器学习和LSTM 三、将一维ECG记录转换为二维图像 四、双模态CNN模型 五、性能评估 参考文献 一、研究对象和ECG记录预处理 本研究采用Chapman大学和Shaoxing人民医院&#xff08;浙江大学医学院绍兴医院&#xff09;收集的12导联…

领导力专题︱如何培养与提升领导力

本文内容结构 一、领导力的核心技能 1、完美领导者&#xff1f; 2、认识你的组织需要什么 3、不同层面领导力共有的特征和技能 4、你的个人行为准则 5、领导风格 6、创造个人影响力 7、完善自己的领导网络 二、领导力与领导者 1、领导力与组织环境 2、领导者还是管理…

2023/4/23总结

项目&#xff1a; 做出了个人信息界面&#xff0c;通过点击头像的方式&#xff1a; 然后就是点击头像可以选择文件&#xff08;后面考虑是存储该文件到自己的文件夹还是只是加载该文件比较好&#xff09;只是能选择文件&#xff0c;写了指定文件后缀名的代码但是好像没什么用…

如何将Edge插件迁移至Google?

问题描述&#xff1a; 因为无法访问谷歌&#xff0c;无法从谷歌插件市场下载插件 第一步&#xff1a;在电脑上找到插件地址 高亮部分&#xff1a;自己电脑上的用户名【不同用户可能会有所不同】 C:\Users\star-dream\AppData\Local\Microsoft\Edge\User Data\Default\Extensi…

rust的现状和未来发展

rust现状: Stack Overflow 的开发者调研显示只有 7% 的开发者在使用 Rust&#xff0c;对比 JavaScript、Python 等语言&#xff0c;使用 Rust 的开发者占比并不高&#xff1b;但从 2016 年开始&#xff0c;Rust 每年都是开发者最爱的编程语言。 根据 JetBrains 2021 年的调研报…

SSH远程访问及控制

文章目录 1.SSH远程管理1.1 SSH的概述1.2 OpenSSH服务器1.3 sshd_ config常用选项设置1.4 SSH端口、配置文件 2.配置OpenSSH服务端2.1 更改端口号2.2 用户登录控制 3.登录验证方式3.1 密码验证3.2 密钥对验证3.3 配置密钥对验证 5.TCP Wrappers访问控制5.1 TCPWrappers机制的基…

第37讲:Python if-elif-else流程控制语句核心概念以及案例演示

文章目录 1.流程控制的概念2.Python中代码块的相关注意事项3.if流程控制语句的语法格式4.if流程控制的简单使用4.1.单分支的if流程控制语句4.2.加else语句的if流程控制4.3.多分支的if流程控制4.4.多分支if代码优化 5.对象的布尔值6.if-else条件表达式6.1.if-else条件表达式语法…