【Java设计模式】这么详细,你还不懂建造者模式嘛!

2023-11-11

我是清风~,每天学习一点点,快乐成长多一点,这些都是我的日常笔记以及总结。

建造者

  • 定义:将一个复杂对象的构建与它的表示分离,使得同样的构建过程可以创建不同的表示。
  • 用户只需指定需要建造的类型就可以得到他们,建造过程及细节不需要知道
  • 型:创建型
    通俗讲,就是建造者模式,就是如何一步一步构建一个包含多个组件的对象,相同的构建过程可以创建不同的产品,比较适用那些流程固定,顺序不一定是固定的。
    对象的建造过程建造细节我不需要知道,但是我也可以创建出复杂的对象。
    打个比方,我们做一盘菜,一盘菜构造过程相对复杂,有人喜欢先放盐,有的人喜欢后放盐,但是放盐这个组件一定要加的。

适用场景

  1. 如果一个对象有非常复杂的内部结构(很多属性)
  2. 想把复杂对象的创建和使用分离

优点

  1. 封装性好,创建和使用分离
  2. 扩展性好、建造类之间独立、一定程度上解耦

缺点

  1. 产生多余的Builder对象
  2. 产品内部发送变化,建造者都要修改,成本较大

建造者模式和工厂模式区别

  1. 建造者模式更注重方法的调用顺序
    工厂模式注重于创建产品
  2. 创建对象的力度不同
    建造者模式可以创建复杂的产品,有各种复杂的部件组成
    工厂模式创建出来的都是一个样子
  3. 关注点
    工厂模式注重的把这个对象创建出来就行了
    而建造者模式不只要创造这个产品,我还要知道这个产品都是由哪些部件组成的。某些应用场景,一定顺序决定产出的产品不一样,也要把顺序进行调整,工厂模式不关心顺序

业务场景

当创造一个对象需要很多步骤时,需要使用建造者模式
当一个简单的方法就可以简单创建整个对象时,适合使用工厂相关模式

建造一个CSDN的课程
课程类

@Data
public class Course {
    /**课程名字**/
    private String courseName;
    /**课程ppt**/
    private String coursePPT;
    /**课程视频**/
    private String courseVideo;
    /**课程笔记**/
    private String courseArticle; 
     /**课程问题解答**/
    private String courseQA;

    @Override
    public String toString() {
        return "Course{" +
                "courseName='" + courseName + '\'' +
                ", coursePPT='" + coursePPT + '\'' +
                ", courseVideo='" + courseVideo + '\'' +
                ", courseArticle='" + courseArticle + '\'' +
                ", courseQA='" + courseQA + '\'' +
                '}';
    }
}

创建抽象类,课程的抽象建造者

public abstract class CourseBuilder {

    /**课程建造者**/
    public abstract void buildCourseName(String courseName);
    public abstract void buildCoursePPT(String coursePPT);
    public abstract void buildCourseVideo(String courseVideo);
    public abstract void buildCourseArticle(String courseArticle);
    public abstract void buildCourseQA(String courseQA);

    /**上面抽象方法写完,就是要交给子类来实现的
     * 就是build各种元素之后,就要制作这个课程**/
    public abstract Course makeCourse();
}

接下来写一个实际的builder的一个子类,就是课程的真正一个buildcourse
继承抽象类

public class CourseActualBuilder extends CourseBuilder {

    private Course course = new Course();


    @Override
    public void buildCourseName(String courseName) {
        course.setCourseName(courseName);
    }

    @Override
    public void buildCoursePPT(String coursePPT) {
        course.setCoursePPT(coursePPT);
    }

    @Override
    public void buildCourseVideo(String courseVideo) {
        course.setCourseVideo(courseVideo);
    }

    @Override
    public void buildCourseArticle(String courseArticle) {
        course.setCourseArticle(courseArticle);
    }

    @Override
    public void buildCourseQA(String courseQA) {
        course.setCourseQA(courseQA);
    }

    @Override
    public Course makeCourse() {
        return course;
    }
}

引入一个检验类
比如公司老板下达课程任务时候,会直接跟课程检验人沟通,这个课程检验人跟制作课程多人进行对接,来共同来制作这个课程。
简单理解,就是课程检验人充当指挥官,制作人提交课程的名字,视频,笔记等,课程校验人通过制作人的提交的资料来瓶装成一个课程

public class Coach {
    private CourseBuilder courseBuilder;

    public void setCourseBuilder(CourseBuilder courseBuilder) {
        this.courseBuilder = courseBuilder;
    }

    /**制作课程**/
    public Course makeCourse(String courseName,String coursePPT,
                             String courseVideo,String courseArticle,
                             String courseQA){
        this.courseBuilder.buildCourseName(courseName);
        this.courseBuilder.buildCoursePPT(coursePPT);
        this.courseBuilder.buildCourseVideo(courseVideo);
        this.courseBuilder.buildCourseArticle(courseArticle);
        this.courseBuilder.buildCourseQA(courseQA);
        return this.courseBuilder.makeCourse();
    }
}

测试

public class Test {
    public static void main(String[] args) {
        CourseBuilder courseBuilder = new CourseActualBuilder();
        Coach coach = new Coach();
        coach.setCourseBuilder(courseBuilder);

        Course course = coach.makeCourse("Java设计模式精讲",
                "Java设计模式精讲PPT",
                "Java设计模式精讲视频",
                "Java设计模式精讲笔记",
                "Java设计模式精讲问答");
        System.out.println(course);

    }
}
输出结果
Course{courseName='Java设计模式精讲', coursePPT='Java设计模式精讲PPT', courseVideo='Java设计模式精讲视频', courseArticle='Java设计模式精讲笔记', courseQA='Java设计模式精讲问答'}

UML类图

首先指挥官校验人和coursebuilder进行组合,一个校验包含一个课程的建造者,他们时一比一的关系,持有的是一个抽象的建造者
CourseActualBuilder实际建造者中只有一个课程类
CourseActualBuilder继承了oursebuilder抽象类,实现里面的抽象方法
test和抽象的builder还有具体的课程没有关系,但是test和校验有关系,它来创建指挥官,指挥官通过组合的方式来使用课程builder抽象类。这里实际使用的CourseActualBuilder,来创建course
应用层通过检验者,拿到了具体的课程类
在这里插入图片描述

源码解析—StringBuilder

类名就能看出来是一个builder
而他的方法append也是经常用的,返回值是他自己在这里插入图片描述
这里有很多重载的append
在这里插入图片描述
最常用的是append一个string类型,首先调用了super父类的append方法,然后返回自己

@Override
    public StringBuilder append(String str) {
        super.append(str);
        return this;
    }

源码分析—SringBuffer

append方法,都加了同步的synchronized关键字
他们都是JDK非常标准的建造者模式
在这里插入图片描述

开源框架—spring中BeanDefinitionBuilder

可以看出来它在这里面创建本身类的类型,然后返回
在这里插入图片描述
它里面的方法都是返回本身定义的类型BeanDefinitionBuilder
这个也是典型的建造者模式
这里的方法设置很多东西,属性,依赖,作用域,工厂方法等等
在这里插入图片描述
建造者在使用也很多很频繁,要熟悉掌握

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

【Java设计模式】这么详细,你还不懂建造者模式嘛! 的相关文章

  • 无法访问类型的封闭实例。 [复制]

    这个问题在这里已经有答案了 整个代码是 public class ThreadLocalTest ThreadLocal
  • Java-线程与CPU的关系

    我对多线程还很陌生 我正在开发一个项目 尝试在我的 Java 程序中使用 4 个 CPU 我想做类似的事情 int numProcessors Runtime getRuntime availableProcessors ExecutorS
  • 设置 SWT Shell 的默认字体

    有没有办法为整个 Shell 设置默认字体 以便任何新控件都将使用相同的字体 看来现在我必须为我创建的每个控件设置字体 这导致了太多的冗余 默认使用的字体由平台选择 请参阅中的其他信息 类字体 SWT 标准小部件工具包 http book
  • 使用 AbstractTableModel 获取 JTable 中选定的行

    我有一个JTable using AbstractTableModel我在哪里有一个JCheckBox在第一列中用于选择行 现在 我需要从已检查的表中获取选定的行 现在 我按顺序从第一行遍历到最后一行并获取所有选择的行 如下所示 List
  • 在Java中清空数组/处理

    除了循环遍历数组中的每个元素并将每个元素设置为 null 之外 Java 处理中是否有一个本机函数可以简单地清空数组 或销毁它 以便能够将其重新声明为新数组 There s Arrays fill myArray null 并不是说它执行的
  • 使用 jpql 和 jpa 从日期字段中提取年份

    我想从数据库中的一行中提取年份部分 以便将其与值进行比较 这是我的功能 public List
  • 在 TestNG 中运行多个类

    我正在尝试自动化一个场景 其中我想登录一次应用程序 然后进行操作而无需再次重新登录 考虑一下 我有在特定类的 BeforeSuite 方法中登录应用程序的代码 public class TestNGClass1 public static
  • 要打乱的键值(整数、字符串)列表的最佳结构

    我需要在 Java 中实现一个结构 它是一个键值列表 类型为整数 字符串 并且我想对其进行洗牌 基本上 我想做类似的事情 public LinkedHashMap
  • 在 Hibernate 中创建 UPDATE RETURNING 查询

    在 Oracle 中 我们可以创建一个更新查询 该查询将使用 RETURNING 子句返回更新的记录 Hibernate中有类似的功能吗 除了数据库生成的值之外 Hibernate 显然不需要返回更新的实例 因为对象传递给Session s
  • 用 java 编写解释器时的 switch 或 if 语句

    当前的作业需要我编写一个程序 以一种非常微小且基本的编程语言 行为有点像 FORTRAN 来读取包含指令的文件并执行这些指令 基本上它是我猜的语言的简单解释器 它是完全线性的 所有语句都是按顺序定义的 并且只有字符串和整数变量 我需要查找和
  • 如何将自定义日志处理程序添加到 Google App Engine?

    我正在尝试向我的 java 应用程序添加自定义日志处理程序 我已经实现了一个扩展 java util Logging Handler 类的 InnerLogger 类 在我的logging properties中声明为处理程序 handle
  • BlackBerry SQLite:将一个 SQLite 数据库连接到另一个

    我正在尝试使用 SQLite 将一个 SQLite 数据库附加到 BlackBerry 上的另一个数据库附加数据库 http www sqlite org lang attach html命令 Database d1 d2 Statemen
  • 从 sbt 程序集运行 uber jar 会导致错误:无法找到或加载主类

    我有一个使用 sbt 程序集插件打包为 uber jar 的 Spark 作业 这build sbt指定一个可运行的 main 作为生成的 uber jar 的目标 mainClass in assembly Some com foo Ba
  • Java:使用 Java.util.concurrent 线程访问读取线程串行端口

    我正在尝试编写一个 Java 串行设备驱动程序并想使用 对我来说是新的 java util concurrent包裹 我有一种发送数据包然后等待 ACK 的方法 我打算有炭 接收在不同的线程中运行 如果接收线程收到 ACK 它应该使用发送数
  • 如何从 Google Custom Search API 获取超过 100 个结果

    我正在尝试使用 Google Custom Search API 在 Java 中进行研究 因此 我需要为每个查询提供一个大的结果集 然而 我似乎仅限于前 100 个结果 这比我需要的要少得多 我使用这样的列表方法 list setStar
  • 我们可以使用 for-each 循环来迭代 Iterator 类型的对象吗? [复制]

    这个问题在这里已经有答案了 如果我们执行以下操作 我们会收到错误 class FGH public static Iterator reverse List list Collections reverse list return list
  • scala中的协变类型参数需要在java接口中保持不变

    我有一个看起来像这样的特征 一些进一步的信息可以在我自己提出了这个相关问题 https stackoverflow com questions 3695990 inheritance and automatic type conversio
  • 读/写带有特殊字符的.txt文件

    I open Notepad Windows 并写 Some lines with special characters Special 并前往另存为 someFile txt 与Encoding set to UTF 8 在Java中我有
  • 编写自定义 Eclipse 调试器

    EDIT 一定有某种方法可以解决这个问题 而无需编写全新的调试器 我目前正在研究在现有 java 调试器之上构建的方法 如果有人对如何获取 Java 调试器已有的信息 有关堆栈帧 变量 原始数据等 有任何想法 那将非常有帮助 我想要做的是我
  • 我找不到 IntelliJ 快捷方式

    我使用 vim 一段时间 我知道有一个 intellij vim 插件 我很好奇内置的 IntelliJ 文本导航存在什么 如何打开实时模板来创建模板 如何查看以 tr 开头的现有模板列表 如何进行全局搜索并在当前文档中进行搜索 然后转到下

随机推荐

  • Acwing 3. 完全背包问题

    暴力解法 完全背包每种物品都有无限个可用 include
  • elementui表格自定义表头的两种方法

    表格自定义表头的方式 多选框表头换文字 请查看上篇博客 http t csdn cn 69De2 文字换按钮 render header render header方法详情 Table column Attributes 参数 说明 类型
  • 时序预测

    MATLAB实现贝叶斯优化CNN GRU时间序列预测 股票价格预测 目录 MATLAB实现贝叶斯优化CNN GRU时间序列预测 股票价格预测 效果一览 基本介绍 模型搭建 程序设计 学习总结 往期精彩 参考资料 效果一览 基本介绍 MATL
  • 苹果系统itunes连iphone连不上服务器,iphone连不上itunes怎么办,iphone连不上itunes的解决办法...

    iPhone连不上iTunes怎么办 苹果手机连接不上iTunes的解决方法 iPhone手机虽然比较贵 但是使用的人也不少 作为一款区别于安卓系统的手机 它拥有更流畅的系统和更好的体验 但是有些果粉平时在操作手机时 有时需要通过连接itu
  • java/php/net/python网上订餐系统设计

    本系统带文档lw万字以上 答辩PPT 查重 如果这个题目不合适 可以去我上传的资源里面找题目 找不到的话 评论留下题目 或者站内私信我 有时间看到机会给您发 系统体系结构 网上订餐系统的结构图4 1所示 图4 1 系统结构 登录系统结构图
  • HashMap的扩容机制

    目录 一 HashMap的底层 二 HashMap的扩容机制原理 1 JDK1 7版本扩容 2 JDK1 8版本扩容 三 HashMap底层JDK1 7到JDK1 8的变化 一 HashMap的底层 底层 采用数组 链表 JDK1 7 采用
  • slam十四讲 _直接法

    视觉里程计 直接法是视觉里程计另一主要分支 它与特征点法有很大不同 虽然它还没有成为现 在 VO 中的主流 但经过近几年的发展 直接法在一定程度上已经能和特征点法平分秋色 特征点法的缺点 关键点的提取与描述子的计算非常耗时 使用特征点时 忽
  • 有序统计恒虚警检测(OS-CFAR)算法的MATLAB代码

    有序统计恒虚警检测 OS CFAR 算法的MATLAB代码 有序统计恒虚警检测 Ordered Statistic Constant False Alarm Rate OS CFAR 是一种常用的雷达信号处理算法 用于检测雷达回波中的目标信
  • TencentOS-tiny 任务间通信(八)- 消息队列

    一 任务间通信 消息队列 概述 消息队列提供了任务间传递指针数据的机制 所谓的 消息 就是指针 消息本身如何解析使用 由传递消息的两个任务自行规定 消息队列不对消息本身做任何规定和限制 消息队列仅承担指针数据的传递义务 API讲解 编程实例
  • uniapp截取数组中的前几项

  • Netty Client 重连实现

    当我们用Netty实现一个TCP client时 我们当然希望当连接断掉的时候Netty能够自动重连 Netty Client有两种情况下需要重连 Netty Client启动的时候需要重连 在程序运行中连接断掉需要重连 对于第一种情况 N
  • 浏览器事件循环机制与Vue nextTick的实现

    浏览器事件循环机制 先上一段简单的代码 console log aa setTimeout gt console log bb 0 Promise resolve then gt console log cc 复制代码 执行结果总是如下 a
  • mariadb实现服务器的数据分库-主从同步

    mariadb实现服务器的数据主从同步1 主从同步配置原理2 使用mariadb实现主从同步 mariadb实现服务器的数据分库 主从同步 1 主从同步配置原理 mariadb主从复制中 第一步 master记录二进制日志 在每个事务更新数
  • C语言之基本算法15—前三位和后三位都是完全平方数的六位完全平方数

    题目 一个六位数是完全平方数 前三位和后三位都是完全平方数 求该三平方数 include
  • 基于机器学习的情绪识别算法matlab仿真,对比SVM,LDA以及决策树

    目录 1 算法理论概述 2 部分核心程序 3 算法运行软件版本 4 算法运行效果图预览 5 算法完整程序工程 1 算法理论概述 情绪识别是一种重要的情感分析任务 旨在从文本 语音或图像等数据中识别出人的情绪状态 如高兴 悲伤 愤怒等 本文介
  • web服务器的简单运用,搭建一个满足些许功能的网站

    实验 搭建一个名为openlab的web网站 网站需求 1 基于域名 www openlab com 可以访问网站内容为 welcom to openlab 2 给该公司创建三个子界面分别显示学生信息 教学资料和缴费网站 基于www ope
  • 数据流式传输_在Android上使用rxjava从家庭影院设备流式传输数据

    数据流式传输 介绍 Introduction In my initial blog post around building an Android companion app for my NAD home cinema receiver
  • LLVM教程(二)-- LLVM的安装

    1 下载CMake版本 https cmake org download 下载的CMake版本必须大于 Version 3 4 3 注如果系统中已经有CMake了通过 cmake version 查看一下版本号 大于就不用下载了 lt 1
  • Windows10 安装 Texlive2019 和 Texstudio

    文章目录 texlive2019的下载与安装 1 下载 2 安装 texstudio的安装及简单设置 1 设置中文界面 2 添加行号 3 设置编译器与编码 4 第一个简单程序 小白人生第一次认识 Latex 一晚上加一上午安装配置成功 参考
  • 【Java设计模式】这么详细,你还不懂建造者模式嘛!

    我是清风 每天学习一点点 快乐成长多一点 这些都是我的日常笔记以及总结 目录 建造者 建造者模式和工厂模式区别 业务场景 UML类图 源码解析 StringBuilder 源码分析 SringBuffer 开源框架 spring中BeanD