Java设计模式 —— 【创建型模式】建造者模式详解

news2025/1/9 14:55:37

文章目录

  • 一、建造者模式
  • 二、案例实现
  • 三、优缺点
  • 四、模式拓展
  • 五、对比
    • 1、工厂方法模式VS建造者模式
    • 2、抽象工厂模式VS建造者模式


一、建造者模式

  1. 建造者模式(Builder Pattern) 又叫生成器模式,是一种对象构建模式。
  2. 它可以将复杂对象的建造过程抽象出来,使这个抽象过程的不同实现方法可以构造出不同表现的对象。
  3. 建造者模式是一步一步创建一个复杂的对象,它允许用户只通过指定复杂对象的类型和内容就可以构建它们,用户不需要知道内部的具体构建细节。
  4. 由于实现了构建和装配的解耦。不同的构建器,相同的装配,也可以做出不同的对象;相同的构建器,不同的装配顺序也可以做出不同的对象。也就是实现了构建算法、装配算法的解耦,实现了更好的复用。
    在这里插入图片描述

建造者(Builder)模式包含如下角色:

  1. Product(产品角色): 要创建的复杂对象。
  2. Builder(抽象建造者):这个接口规定要实现复杂对象的那些部分的创建,并不涉及具体的部件对象的创建。
  3. ConcreteBuilder(具体建造者):实现 Builder 接口,完成复杂产品的各个部件的具体创建方法。在构造过程完成后,提供产品的实例。
  4. Director(指挥者): 调用具体建造者来创建复杂对象的各个部分,在指导者中不涉及具体产品的信息,只负责保证对象各部分完整创建或按某种顺序创建。

二、案例实现

以生产手机为例:

Builder(抽象建造者):定义手机需要那些配件
具体建造者:定义不同手机配件的生产标准
Director(指挥者):定义手机需要组装什么配件,按照什么顺序进行组装

在这里插入图片描述
产品角色(Phone):

public class Phone {
    private String cpu;
    private String memory;
    private String colour;
    public void setCpu(String cpu) {
        this.cpu = cpu;
    }
    public void setMemory(String memory) {
        this.memory = memory;
    }
    public void setColour(String colour) {
        this.colour = colour;
    }

    @Override
    public String toString() {
        return "Phone{" +
                "cpu='" + cpu + '\'' +
                ", memory='" + memory + '\'' +
                ", colour='" + colour + '\'' +
                '}';
    }
}

抽象建造者(Builder):

public abstract class Builder {
    protected Phone phone = new Phone();
    public abstract void buildCpu();
    public abstract void buildMemory();
    public abstract void buildColour();
    public Phone builder(){
        return phone;
    }
}

具体建造者(XiaoMi,HuaWei):

public class XiaoMi extends Builder {

    @Override
    public void buildCpu() {
        phone.setCpu("天机");
    }

    @Override
    public void buildMemory() {
        phone.setMemory("256");
    }

    @Override
    public void buildColour() {
        phone.setColour("白色");
    }
}

public class HuaWei extends Builder {

    @Override
    public void buildCpu() {
        phone.setCpu("麒麟");
    }

    @Override
    public void buildMemory() {
        phone.setMemory("512");
    }

    @Override
    public void buildColour() {
        phone.setColour("黑色");
    }
}

指挥者(Director):

public class Director {
    private Builder builder;

    public void setBuilder(Builder builder){
        this.builder = builder;
    }

    public Phone createPhone() {
        builder.buildCpu();
        builder.buildMemory();
        builder.buildColour();
        return builder.builder();
    }
}

测试:

public class Demo {
    public static void main(String[] args) {
        Director director = new Director();
        director.setBuilder(new XiaoMi());
        Phone xiaoMi = director.createPhone();
        System.out.println("XiaoMi: " + xiaoMi);

        director.setBuilder(new HuaWei());
        Phone huaWei = director.createPhone();
        System.out.println("HuaWei: " + huaWei);
    }
}

在这里插入图片描述


三、优缺点

优点:

  • 建造者模式的封装性很好。使用建造者模式可以有效的封装变化,在使用建造者模式的场景中,一般产品类和建造者类是比较稳定的,因此,将主要的业务逻辑封装在指挥者类中对整体而言可以取得比较好的稳定性。
  • 在建造者模式中,客户端不必知道产品内部组成的细节,将产品本身与产品的创建过程解耦,使得相同的创建过程可以创建不同的产品对象。
  • 可以更加精细地控制产品的创建过程 。将复杂产品的创建步骤分解在不同的方法中,使得创建过程更加清晰,也更方便使用程序来控制创建过程。
  • 建造者模式很容易进行扩展。如果有新的需求,通过实现一个新的建造者类就可以完成,基本上不用修改之前已经测试通过的代码,因此也就不会对原有功能引入风险。符合开闭原则。

缺点:

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


四、模式拓展

建造者模式除了上面的用途外,在开发中还有一个常用的使用方式,就是当一个类构造器需要传入很多参数时,如果创建这个类的实例,代码可读性会非常差,而且很容易引入错误,此时就可以利用建造者模式进行重构。

比如上述案例中,手机又要定制摄像头,屏幕,电池等等,使用构造方法创建对象,代码的可读性及使用的成本就是比较高。

我们对代码进行优化:

public class Phone {

    private String cpu;
    private String memory;
    private String colour;

    private Phone(Builder builder) {
        cpu = builder.cpu;
        memory = builder.memory;
        colour = builder.colour;
    }

    public static class Builder {
        private String cpu;
        private String memory;
        private String colour;
        public Builder() {}
        public Builder cpu(String val) {
            cpu = val;
            return this;
        }
        public Builder memory(String val) {
            memory = val;
            return this;
        }
        public Builder colour(String val) {
            colour = val;
            return this;
        }
        public Phone build() {
            return new Phone(this);
        }
    }
    @Override
    public String toString() {
        return "Phone{" +
                "cpu='" + cpu + '\'' +
                ", memory='" + memory + '\'' +
                ", colour='" + colour + '\'' +
                '}';
    }
}
public class Demo {
    public static void main(String[] args) {
        Phone phone = new Phone.Builder()
                .cpu("天玑")
                .memory("256")
                .colour("白色")
                .build();
        System.out.println(phone);
    }
}

五、对比

1、工厂方法模式VS建造者模式

  • 工厂方法模式注重的是整体对象的创建方式;而建造者模式注重的是部件构建的过程,意在通过一步一步地精确构造创建出一个复杂的对象。

  • 我们举个简单例子来说明两者的差异,如要制造一个超人,如果使用工厂方法模式,直接产生出来的就是一个力大无穷、能够飞翔、内裤外穿的超人;而如果使用建造者模式,则需要组装手、头、脚、躯干等部分,然后再把内裤外穿,于是一个超人就诞生了。

  • 如果用工厂方法建造手机的话,直接就可以得到一个完整的手机,而用建造者模式,则需要按照指定顺序组装各个零件,才能得到一部手机。

2、抽象工厂模式VS建造者模式

  • 抽象工厂模式实现对产品家族的创建,一个产品家族是这样的一系列产品:具有不同分类维度的产品组合,采用抽象工厂模式则是不需要关心构建过程,只关心什么产品由什么工厂生产即可。

  • 建造者模式则是要求按照指定的蓝图建造产品,它的主要目的是通过组装零配件而产生一个新产品。

  • 如果将抽象工厂模式看成汽车配件生产工厂,生产一个产品族的产品,那么建造者模式就是一个汽车组装工厂,通过对部件的组装可以返回一辆完整的汽车。

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

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

相关文章

单链表(C语言版本)

前提 不探讨头结点空链表可以插入和查找,不可删除一般不选择phead移动,定义一个新结点把phead赋给他,移动新结点即可单链表不适合在前面和后面插入或删除,适合在后面插入删除 头插 void SLPushFront(SLTNode** pphead, SLTDataTy…

VMware虚拟机搭建和镜像配置

VMware虚拟机搭建和镜像配置 下载安装VMware 开始下载 更改安装路径,需要一个大空间的盘 更改后下一步 下一步后,选择不主动升级更新 一直下一步 直到安装完毕 输入许可密钥,我下载的版本是12,输入完成点击输入&#xff…

使用PPT科研绘图导出PDF边缘留白问题解决方案

使用PPT画图导出PDF格式后,边缘有空白,插入latex不美观,解决方案为自定义PPT幻灯片母版大小,如题步骤为: 1、查看已制作好的图片的大小,即长度和宽度 2、选择自定义幻灯片大小 3、自定义幻灯片大小为第1…

在Ubuntu上使用docker compose安装N卡GPU的Ollama服务

在现代计算环境中,利用 GPU 进行计算加速变得越来越重要。下面将讲解如何在Ubuntu上使用docker compose安装N卡GPU的Ollama服务。 1、安装 NVIDIA 容器工具 首先,需要确保你的系统已经安装了 NVIDIA 容器工具 nvidia-container-toolkit。这是让 Docker 容器访问 GPU 的关键…

如何借助前端表格控件实现金融投资分析平台?

最新技术资源(建议收藏) https://www.grapecity.com.cn/resources/ 金融投资分析背景介绍 金融投资分析是金融领域的核心活动,它要求对资产、市场及经济数据进行深入研究,以识别并评估潜在的投资机会与风险。这一过程融合了宏观经…

01_Node.js入门 (黑马)

01_Node.js入门 知识点自测 从 index.js 出发&#xff0c;访问到 student/data.json 的相对路径如何写? A&#xff1a;../public/teacher/data.json B&#xff1a;./public/student/data.json C&#xff1a;../student/data.json <details><summary>答案</sum…

快速构建NLP理论知识体系

NLP理论知识体系 一句话解释NLPNLP模型及原理简述1、Rag 一句话解释NLP 如果我们要实现机器翻译、情感分析、问答系统、文本摘要、聊天机器人、构造智能化的辅助文件填写模板&#xff0c;NLP可以通过现成的模型对输入的语音、文字、图片进行处理&#xff08;分词、标词性、去停…

Python:import语句的详细解析(绝对路径导入和相对路径导入)

相关阅读 Pythonhttps://blog.csdn.net/weixin_45791458/category_12403403.html?spm1001.2014.3001.5482 import语句是Python中一个很重要的机制&#xff0c;允许在一个文件中访问另一个文件的函数、类、变量等&#xff0c;本文就将进行详细介绍。 在具体谈论import语句前&a…

CUDA 计时功能,记录GPU程序/函数耗时,cudaEventCreate,cudaEventRecord,cudaEventElapsedTime

为了测试GPU函数的耗时&#xff0c;可以使用 CUDA 提供的计时功能&#xff1a;cudaEventCreate, cudaEventRecord, 和 cudaEventElapsedTime。这些函数可以帮助你测量某个 CUDA 操作&#xff08;如设置设备&#xff09;所花费的时间。 一、记录耗时案例 以下是一个示例程序&a…

数字图像处理(15):图像平移

&#xff08;1&#xff09;图像平移的基本原理&#xff1a;计算每个像素点的移动向量&#xff0c;并将这些像素按照指定的方向和距离进行移动。 &#xff08;2&#xff09;平移向量包括水平和垂直分量&#xff0c;可以表示为&#xff08;dx&#xff0c;dy&#xff09;&#xff…

Hyper-V安装Win11虚拟机并设置vGPU显卡直通

一、为什么我使用Hyper-V虚拟机 我的宿主机是Win11,想装一个Win10或Win11虚拟机。但是我用VMware安装Win10或Win11后,随机地蓝屏,非常烦人,估计是和宿主机的某些设置有关,或者宿主机电脑硬件比较新(我电脑装Win10就会蓝屏,Win11就不会),某些特性不支持。 所以我就安…

Qt Xlsx安装教程

Qt Xlsx安装教程 安装perl 如果没有安装perl&#xff0c;请参考perl Window安装教程 下载QtXlsxWriter源码 下载地址 ming32-make编译32 lib库 C:\Qt\Qt5.12.12\5.12.12\mingw73_32>d: D:\>cd D:\Code\QtXlsxWriter-master\QtXlsxWriter-master D:\Code\QtXlsxWrit…

C# RSA加密和解密,RSA生成私钥和公钥

C# RSA加密和解密&#xff0c;RSA生成私钥和公钥&#xff08;使用XML格式秘钥&#xff09; 目录 前言生成xml格式的公钥和私钥 PrivateKeyPublicKey测试加密、解密 方案1&#xff1a;RSA公钥加密&#xff0c;RSA私钥解密方案2&#xff1a;RSA私钥加密&#xff0c;RSA私钥解密…

【Rive】Android与Rive交互

1 Android与Rive交互的常用接口 1.1 RiveAnimationView参数 <app.rive.runtime.kotlin.RiveAnimationViewandroid:id"id/rive_view"android:layout_width"match_parent"android:layout_height"match_parent"android:adjustViewBounds"…

捷米特 EtherNet/IP 总线协议网关的具体内容介绍

关于EtherNET/IP的基本介绍 EtherNet/IP 中的 “Ethernet” 指以太网&#xff0c;是一种常见的局域网技术&#xff0c;用于在有限区域内实现多台设备之间的数据传输&#xff1b;“IP” 在此处指工业协议&#xff08;Industrial Protocol&#xff09;&#xff0c;而不是通常所说…

Python 读取 Excel 表格并导出为 DBF 文件

以下是将上述代码封装为函数的版本。函数接收 input_excel_path、sheet_name 和 output_dbf_path 作为参数&#xff0c;按照需求读取 Excel 表格并导出为 DBF 文件。 封装函数代码 import pandas as pd import dbfdef excel_to_dbf(input_excel_path, sheet_name, output_dbf_…

使用 ASP.NET Core HttpLoggingMiddleware 记录 http 请求/响应

我们发布了一个应用程序&#xff0c;该应用程序运行在一个相当隐蔽的 WAF 后面。他们向我们保证&#xff0c;他们的产品不会以任何方式干扰我们的应用程序。这是错误的。他们删除了我们几乎所有的“自定义”标头。为了“证明”这一点&#xff0c;我构建了一个中间件&#xff0c…

EasyExcel改名为FastExce做了那些改变呢

回到&#xff1a;github原作者地址&#xff1a;https://github.com/CodePhiliaX/fastexcel 中文 |English | 什么是 FastExcel FastExcel 是由原 EasyExcel 作者创建的新项目。2023 年我已从阿里离职&#xff0c;近期阿里宣布停止更新 EasyExcel&#xff0c;作者他本人决定继…

TCP/IP协议详解(小白)

TCP/IP协议详解 TCP/IP协议包含了一系列的协议&#xff0c;也叫TCP/IP协议族&#xff08;TCP/IP Protocol Suite&#xff0c;或TCP/IP Protocols&#xff09;&#xff0c;简称TCP/IP。TCP/IP协议族提供了点对点的连结机制&#xff0c;并且将传输数据帧的封装、寻址、传输、路由…

【工具】音频文件格式转换工具

找开源资源、下载测试不同库的效果&#xff0c;然后找音频、下载音频、编写代码、测试转换、流程通畅。写一个工具花的时间越来越多了&#xff01;这个 5 天 这个工具是一个音频文件格式转换工具&#xff0c;支持对 mp3.aac.wav.caf.flac.ircam.mp2.mpeg.oga.opus.pcm.ra.spx.…