【设计模式学习】11种高频设计模式之建造者模式

2023-11-16


相关介绍

1、定义

将一个复杂对象的构建与它的表示分离,使得同样得构建过程可以创建不同得表示。

2、 作用

在用户不知道对象得建造过程和细节的情况下就可以直接创建复杂的对象。

3、理解

用户只需要给出指定复杂对象的类型和内容,建造者模式负责按顺序创建复杂的对象(把内部的建造过程和细节隐藏起来)。角色分析如下:
在这里插入图片描述

4、用法

  • 常规用法

导演类Director在Builder模式种具有很重要的作用,它用于指挥具体构建者如何构建产品,控制调用先后次序,并向调用者返回完整的产品类,但是有些情况下需要简化系统结构,可以把Director和抽象建造者进行结合。
在实际情况中,服务员(具体建造者)可以随意搭配几种产品(零件)组成一款套餐(产品),然后出售给客户。

  • 静态内部类方式

该方式实现零件无序装配构造,这种方式使用更加灵活,更符合定义。内部有复杂对象的默认实现,使用时可以根据用户需求自由定义更改内容,并且无需改变具体的构造方式,就可以生产出不同复杂产品。
在实际情况中,把指挥者交给用户操作,使得产品的创建更加灵活简单(可以选择改变套餐中的搭配)。

5、 优点

  • 产品的建造和表示分离,实现了解耦。使用建造者模式可以是客户端不必知道产品内部组成的细节。
  • 将复杂产品的创建步骤分解在不同的方法中,使得创建过程更加清晰。
  • 具体的建造者类之间是相互独立的,这有利于系统的扩展。增加新的具体建造者无需修改原有类库的代码,符合“开闭原则”。

6、 缺点

  • 建造者模式所创建的产品一般具有较多的共同点,其组成部分相似;如果产品之间的差异性很大,则不适合使用建造者模式,因此其适用范围受到一定的限制。
  • 如果产品的 内部变化复杂,可能会导致需要定义很多具体建造者类来实现这种变化,导致系统变得很庞大

7、 例子

  • 工厂(建造者模式):负责制造汽车(组装过程和细节再在工厂内)
  • 汽车购买者(用户):你只需要说出你需要的型号(对象的类型和内容),然后直接购买就可以使用了(不需要知道汽车是怎么组装的(车轮、车门、发动机、方向盘等))

代码介绍

常规用法

代码目录如下:
在这里插入图片描述
Builder类

package builder.general;

//抽象的建造者:方法
public abstract class Builder {
    abstract void buildA();     //地基
    abstract void buildB();     //钢筋工程
    abstract void buildC();     //铺电线
    abstract void buildD();     //粉刷

    abstract Product getProduct();
}

Product类

package builder.general;

//产品:房子
public class Product {
    private String buildA;
    private String buildB;
    private String buildC;
    private String buildD;

    public String getBuildA() {
        return buildA;
    }

    public void setBuildA(String buildA) {
        this.buildA = buildA;
    }

    public String getBuildB() {
        return buildB;
    }

    public void setBuildB(String buildB) {
        this.buildB = buildB;
    }

    public String getBuildC() {
        return buildC;
    }

    public void setBuildC(String buildC) {
        this.buildC = buildC;
    }

    public String getBuildD() {
        return buildD;
    }

    public void setBuildD(String buildD) {
        this.buildD = buildD;
    }

    @Override
    public String toString() {
        return "Product{" +
                "buildA=" + buildA +
                ", buildB=" + buildB +
                ", buildC=" + buildC +
                ", buildD=" + buildD +
                '}';
    }
}

Worker类

package builder.general;

//具体的建造者:工人
public class Worker extends Builder{
    private Product product;

    //注意这里!!!工人负责创建产品对象
    public Worker(){
        product=new Product();
    }

    @Override
    void buildA() {
        product.setBuildA("地基");
        System.out.println("地基");
    }

    @Override
    void buildB() {
        product.setBuildB("钢筋工程");
        System.out.println("钢筋工程");
    }

    @Override
    void buildC() {
        product.setBuildC("铺电线");
        System.out.println("铺电线");
    }

    @Override
    void buildD() {
        product.setBuildD("粉刷");
        System.out.println("粉刷");
    }

    @Override
    Product getProduct(){
        return product;
    }

Director类

package builder.general;

//指挥:核心。负责只会构建一个工程,工程如何构建。由它决定
public class Director {
    //指挥工人按照顺序完成任务
    public Product build(Builder builder){
        builder.buildA();
        builder.buildB();
        builder.buildC();
        builder.buildD();

        return builder.getProduct();
    }
}

Test类

package builder.general;

public class Test {
    public static void main(String[]args){
        //指挥
        Director director=new Director();
        //指挥具体的工人完成产品
        Product build=director.build(new Worker());
        System.out.println(build.toString());
    }
}

静态内部类方法

代码目录如下:
在这里插入图片描述

Builder类

package builder.staticInner;

//抽象的建造者:方法
public abstract class Builder {
    abstract Builder buildA(String msg);     //汉堡
    abstract Builder buildB(String msg);     //薯条
    abstract Builder buildC(String msg);     //可乐
    abstract Builder buildD(String msg);     //甜点

    abstract Product getProduct();
}

Product类

package builder.staticInner;

//产品:套餐
public class Product {
    private String buildA="汉堡";
    private String buildB="可乐";
    private String buildC="薯条";
    private String buildD="甜点";

    public String getBuildA() {
        return buildA;
    }

    public void setBuildA(String buildA) {
        this.buildA = buildA;
    }

    public String getBuildB() {
        return buildB;
    }

    public void setBuildB(String buildB) {
        this.buildB = buildB;
    }

    public String getBuildC() {
        return buildC;
    }

    public void setBuildC(String buildC) {
        this.buildC = buildC;
    }

    public String getBuildD() {
        return buildD;
    }

    public void setBuildD(String buildD) {
        this.buildD = buildD;
    }

    @Override
    public String toString() {
        return "Product{" +
                "buildA=" + buildA +
                ", buildB=" + buildB +
                ", buildC=" + buildC +
                ", buildD=" + buildD +
                '}';
    }
}

Worker类

package builder.staticInner;

//具体的建造者:服务员
public class Worker extends Builder {
    private Product product;

    //服务员负责创建产品对象
    public Worker(){
        product=new Product();
    }

    @Override
    Builder buildA(String msg) {
        product.setBuildA(msg);
        return this;        //this指当前调用buildA的worker,可以实现链式构建
    }

    @Override
    Builder buildB(String msg) {
        product.setBuildB(msg);
        return this;
    }

    @Override
    Builder buildC(String msg) {
        product.setBuildC(msg);
        return this;
    }

    @Override
    Builder buildD(String msg) {
        product.setBuildD(msg);
        return this;
    }

    @Override
    Product getProduct() {
        return product;
    }
}

Test类

package builder.staticInner;

public class Test {
    public static void main(String[] args){
        //服务员
        Worker worker=new Worker();
        //链式编程:在原来的基础上,可以自由组合,如果不组合也有默认的套餐
        Product product=worker.buildC("辣条").buildA("奶茶").getProduct();

        System.out.println(product.toString());
    }
}

系列文章目录

一、单例模式
二、工厂模式
三、建造者模式
四、原型模式
五、适配器模式
六、代理模式
七、装饰器模式
八、迭代器模式
九、模板方法模式
十、策略模式
十一、责任链模式
十二、观察者模式
总结、12种常用设计模式


参考资料

【狂神说Java】单例模式-23种设计模式系列

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

【设计模式学习】11种高频设计模式之建造者模式 的相关文章

随机推荐

  • Windows中杀死占用某个端口的进程

    最近写项目 总是出现端口被占用的问题 原来傻傻的把电脑重启一下 终于有一天受不了了 想要想办法解决 刚开始从网上找了好多教程 发现不行 开始自己尝试 终于 成功的将占用端口的进程杀掉 在此记录下过程 以8080端口为例 第一步 打开cmd命
  • NLP--BPE、WordPiece、ULM、SentencePiece子词分词器总结【原理】

    序言 当我们在做英语文本任务时 机器无法理解文本 当我们将句子序列送入模型时 模型仅仅能看到一串字节 它无法知道一个词从哪里开始 到哪里结束 所以也不知道一个词是怎么组成的 所以 为了帮助机器理解文本 我们需要 将文本分成一个个小片段 然后
  • leetcode目录

    最近写的题目还没有填到本目录中 可以在去文章列表查看 本目录正在持续更新中 题目 考点 时间 分值 最大利润 贪心算法 2023 Q1 100 施肥问题 逻辑推理 2023 Q1 100 组装数组 深度优先搜索 2023 Q1 200 开租
  • android Button背景高度被拉伸问题--解决方案

    接入第三方SDK后 发现SDK提供的弹窗里 有两个按钮的高度呈被拉伸状态 而 第三方提供的demo内 这两个按钮均呈正常状态 对于第一次接触Android的菜鸟来说 这个问题颇为难解 第三方在尝试了几种方法之后 也宣告失败 这种奇葩问题 让
  • element项目中遇到的小问题总结

    在用element UI框架做项目时遇到的问题 现在总结记录下来 此文档持续更新中 1 日期选择器el date picker赋值后再次修改时页面不回显
  • JS逆向进阶案例

    前情回顾 有道翻译参数破解 百度翻译参数破解 之前 我们介绍了两种基础的JS逆向案例 今天 就继续来分享一个稍微复杂的JS逆向案例吧 目录 一 寻找加密源码 二 查漏补全JS代码 三 全部代码 爬取网址 某网站 本次爬取仅供学习 无任何商业
  • Mac上安装双系统

    写在前面 Mac用户在使用过程中 多少有的时候还会使用Windows 想装一个咋办 找某宝需要花钱150元 看这篇文章 十几分钟看明白 自己动手丰衣足食 所以本文将以图文教程教你如何安装双系统 开机随意选择 想用什么用什么 尽管我不是很喜欢
  • FFmpeg 采用源码安装 、环境配置、卸载

    https blog csdn net qq 36397240 article details 107745149 FFmpeg 采用源码安装 环境配置 卸载 验证了几种ffmpeg x264安装方法 这篇文章清晰简洁 特别是对环境配置介绍
  • AES(加密,填充,模式)新手小结

    本小结的密码学术语如填充 模式 等等 均以AES为例进行说明 举一反三 其他算法涉及的相同术语 大致也就理解是怎么回事了 吧 1 AES https nvlpubs nist gov nistpubs FIPS NIST FIPS 197
  • 【电子电路】五款单按键开关机电路图

    一 单按键开关机电路图 本例电路可实现通过按一次按键S1实现开机 再按一次S1实现关机的功能 整个电路的工作过程 电路中连接器P1是一个电源连接器 电源 从1 2脚输入 电源地从3 4脚输入 电路上电后 P MOS管Q1的G极和S极都是为高
  • Matatalab:编程只是大人的专利?这款儿童实物编程机器人了解一下

    转自 http www sohu com a 294483601 485557 创始人 https www tianyancha com brand b5813253827 CEO 苏荣星 MatataLab CEO 曾任职 mBot Ra
  • 基于入侵杂草算法的函数寻优算法

    文章目录 一 理论基础 1 算法简介 2 杂草特性 二 案例背景 1 问题描述 2 解题思路及步骤 1 初始化种群 2 繁殖 3 空间分布 4 竞争性排斥规则 3 算法流程 三 MATLAB程序实现 1 清空环境变量 2 问题设定 3 参数
  • 用matlab计算超调,怎样用matlab计算超调量、峰值时间

    2018 01 19 Intel Xeon E5 2697 v2的CPU的峰值计算能力和Intel Xeon E7 8870的CPU的峰值计算能力哪个强 必然Xeon E5 2697 v2运算能力强 首先 看核心数 Xeon E5 2697
  • 动态环境下基于强化学习的无人机任务路径规划

    路径规划主要是指无人机环境中存在威胁障碍物 然后 规划无人机从起点到目的地避开障碍物的最佳路线也是无人机实现自主飞行的主要因素之一 在无人机的任务分配中 主要目的是增强无人机的时间性能和环境适应性 对于无人机的路径规划水平 修改和改进算法可
  • STL--map的应用

    STL之map的应用 map定义及用途 map翻译为映射 是STL中的常用容器 其实 数组就是一种映射 比如 int a 100 就是定义了一个int到int的映射 而a 5 25 就是把5映射到25 数组总是将int类型映射到其它基本类型
  • oracle优化-----监控指标

    author skatetime 2010 03 24 昨天一个朋友问我 如何优化数据库 在想优化数据库前 首先要确认数据库是否需要优化 这就需要一些监控指标了 如 事务响应时间 数据库的逻辑读 数据库的物理读 物理写等 日常监控这些指标
  • GetProcAddress错误码127

    表现为明明loadLibrary GetProcAddress就是拿不到地址 原因是C语言的函数使用C 编译时需要加上extern C 转载于 https www cnblogs com Jacket K p 11574624 html
  • 十个经典免费软件和五★级网站!

    十个经典免费软件和五 级网站 软件非常实用 都是 免费版本 ghost 诺顿杀毒 等经典软件哪里皆可下载到 就没列出 推荐的网站则是very出色实用 lt 一 gt 软件 1 代理甭猎手 v1 0 179 KB 绿色 推荐指数 介绍 全称是
  • 【目标检测之数据集预处理】继承Dataset定义自己的数据集【附代码】

    在深度学习训练中 除了设计有效的卷积神经网络框架外 更重要的是数据的处理 在训练之前需要对训练数据进行预处理 比如在目标检测网络训练中 首先需要划分训练集和测试集 然后对标签 边界框等进行处理后才能送入网络进行训练 本文章以VOC数据集格式
  • 【设计模式学习】11种高频设计模式之建造者模式

    文章目录 相关介绍 代码介绍 常规用法 静态内部类方法 系列文章目录 参考资料 相关介绍 1 定义 将一个复杂对象的构建与它的表示分离 使得同样得构建过程可以创建不同得表示 2 作用 在用户不知道对象得建造过程和细节的情况下就可以直接创建复