设计模式 创建型 建造者模式(Builder Pattern)与 常见技术框架应用 解析

在这里插入图片描述

单例模式(Singleton Pattern),又称生成器模式,是一种对象构建模式。它主要用于构建复杂对象,通过将复杂对象的构建过程与其表示分离,使得同样的构建过程可以创建出具有不同表示的对象。该模式的核心思想是将一个复杂对象的构建过程分解为多个简单的步骤,并允许用户通过指定复杂对象的类型和内容来构建它们,而无需知道对象内部的具体构建细节。

一、核心思想

建造者模式的核心思想是将复杂对象的构建过程与它的表示分离,使得构建过程可以灵活地组合,而不会影响最终的产品表示。这有助于创建一个逐步构建的复杂对象,同时隐藏其内部构造细节。

二、定义与结构

  • 定义:建造者模式是一种创建型设计模式,它允许将一个复杂对象的构建与其表示分离,使得同样的构建过程可以创建不同的表示。通过将对象的构建过程分解为一系列步骤,由不同的建造者类来实现这些步骤,最后由指挥者类来统筹构建流程,以得到最终的复杂对象。
  • 结构
    • 产品(Product):即要构建的复杂对象,它具有多个组成部分,这些部分通常由建造者逐步构建完成。例如上述的定制电脑,它就是产品,包含 CPU、内存等各种硬件组件作为其内部属性。
    • 抽象建造者(Abstract Builder):定义了构建产品各个部分以及返回最终产品的抽象方法,为具体建造者提供统一的接口规范。比如定义了安装 CPU、安装内存等抽象操作方法。
    • 具体建造者(Concrete Builder):实现抽象建造者接口,负责按照特定的需求实际构建产品的各个部分,并在最后返回构建完成的产品。例如,高性能电脑建造者会选择高端的 CPU、大容量内存来组装电脑。
    • 指挥者(Director):负责指挥和协调建造者的构建步骤,它知晓构建产品所需的完整流程,通过调用建造者的方法来实现产品的构建,但它并不负责具体的构建细节,只是掌控构建的节奏。比如指挥者决定先安装哪个部件,后安装哪个部件。

角色

  • 产品角色(Product):作为建造的目标对象,它承载了复杂对象的所有属性和状态,是建造者们努力打造的成果,通常是一个包含多个成员变量的类,这些变量代表了对象的不同组成部分。
  • 抽象建造者角色(Abstract Builder):作为建造者的抽象模板,规定了构建产品必须实现的一组抽象方法,这些方法涵盖了从基础部件安装到最终产品组装成型的各个环节,为具体建造者的实现提供了方向指引。
  • 具体建造者角色(Concrete Builder):依据抽象建造者的蓝图,深入到实际构建工作的第一线,根据特定的设计要求或用户需求,精心挑选合适的部件,运用专业的技术,将一个个零散的部件逐步组装成完整的产品,并且能够将最终成果交付给客户端。
  • 指挥者角色(Director):站在更高的层面统筹规划,它熟悉整个构建流程的最优顺序,通过向具体建造者下达精准的指令,协调各个建造者之间的工作衔接,确保复杂对象能够高效、有序地构建完成,虽然不直接参与物理构建,但却掌控着构建的全局节奏。

三、实现步骤及代码示例(以构建一个网页表单为例)

1、定义产品

// 产品:网页表单
public class WebForm {
    private String formTitle;
    private String formFields;
    private String submitButtonText;

    public WebForm(String formTitle, String formFields, String submitButtonText) {
        this.formTitle = formTitle;
        this.formFields = formFields;
        this.submitButtonText = submitButtonText;
    }

    // 省略 getters 和 setters,方便展示主要逻辑

    @Override
    public String toString() {
        return "WebForm{" +
                "formTitle='" + formTitle + '\'' +
                "formFields='" + formFields + '\'' +
                "submitButtonText='" + submitButtonText + '\'' +
                '}';
    }
}

2、定义抽象建造者

// 抽象建造者:网页表单建造者
public abstract class WebFormBuilder {
    protected WebForm webForm;

    public WebForm getWebForm() {
        return webForm;
    }

    public abstract void buildFormTitle();
    public abstract void buildFormFields();
    public abstract void buildSubmitButtonText();
}

3、创建具体建造者

// 具体建造者:登录表单建造者
public class LoginFormBuilder extends WebFormBuilder {
    @Override
    public void buildFormTitle() {
        webForm = new WebForm("Login Form", "", "");
    }

    @Override
    public void buildFormFields() {
        webForm.setFormFields("Username: <input type='text' name='username'><br>Password: <input type='password' name='password'>");
    }

    @Override
    public void buildSubmitButtonText() {
        webForm.setSubmitButtonText("Login");
    }
}

// 具体建造者:注册表单建造者
public class RegistrationFormBuilder extends WebFormBuilder {
    @Override
    public void buildFormTitle() {
        webForm = new WebForm("Registration Form", "", "");
    }

    @Override
    public void buildFormFields() {
        webForm.setFormFields("Username: <input type='text' name='username'><br>Password: <input type='password' name='password'><br>Email: <input type='email' name='email'>");
    }

    @Override
    public void buildSubmitButtonText() {
        webForm.setSubmitButtonText("Register");
    }
}

4、再定义指挥者:

// 指挥者:表单指挥者
public class FormDirector {
    private WebFormBuilder webFormBuilder;

    public FormDirector(WebFormBuilder webFormBuilder) {
        this.webFormBuilder = webFormBuilder;
    }

    public WebForm construct() {
        webFormBuilder.buildFormTitle();
        webFormBuilder.buildFormFields();
        webFormBuilder.buildSubmitButtonText();
        return webFormBuilder.getWebForm();
    }
}

5、在客户端代码中使用

public class Main {
    public static void main(String[] args) {
        // 构建登录表单
        LoginFormBuilder loginFormBuilder = new LoginFormBuilder();
        FormDirector formDirector = new FormDirector(loginFormBuilder);
        WebForm loginForm = formDirector.construct();
        System.out.println(loginForm);

        // 构建注册表单
        RegistrationFormBuilder registrationFormBuilder = new RegistrationFormBuilder();
        formDirector = new FormDirector(registrationFormBuilder);
        WebForm registrationForm = formDirector.construct();
        System.out.println(registrationForm);
    }
}

四、常见技术框架应用

建造者模式(Builder Pattern)是一种创建型设计模式,它通过将复杂对象的构建过程与其表示分离,使得同样的构建过程可以创建不同的表示。这种模式的优点在于能够分步骤构建复杂对象,而无需关注这些部分的具体组装过程,从而提高了代码的灵活性和可扩展性。关于建造者模式在技术框架中的应用,虽然具体的应用场景可能因框架而异,但以下是一些常见的技术框架和领域中建造者模式的应用示例:

1、Java EE和Spring框架

在Java EE和Spring等企业级应用框架中,建造者模式常用于构建具有复杂属性和依赖关系的对象。例如,在构建数据库连接池、消息队列连接等复杂对象时,可以使用建造者模式来逐步设置对象的属性,并最终返回一个配置好的实例。

2、Web开发框架

在Web开发中,建造者模式常用于构建HTTP请求和响应对象。这些对象通常包含多个属性和配置选项,如URL、请求方法、头信息、请求体等。通过建造者模式,可以逐步设置这些属性,而不是在构造函数中一次性传递所有参数。

3、图形用户界面(GUI)框架

在构建复杂的GUI组件时,如窗口、按钮、文本框等,建造者模式可以帮助开发者逐步设置组件的属性,如大小、位置、颜色等。这样不仅可以提高代码的可读性,还可以使组件的创建过程更加灵活和可扩展。

4、游戏开发框架

在游戏开发中,建造者模式常用于构建游戏中的角色、道具、场景等复杂对象。通过建造者模式,可以逐步设置这些对象的属性,如生命值、攻击力、防御力等,并最终生成一个完整的游戏对象。

5、配置和初始化框架

在一些配置和初始化框架中,建造者模式常用于构建配置对象。这些配置对象通常包含多个配置项和依赖关系,通过建造者模式可以逐步设置这些配置项,并最终生成一个配置好的实例。

在 Android 开发中,AlertDialog 的创建就运用了类似建造者模式的思想。

import android.app.AlertDialog;
import android.content.Context;
import android.content.DialogInterface;

public class DialogBuilderExample {
    public static void main(String[] args) {
        Context context = null; // 实际开发中需替换为有效的上下文
        AlertDialog.Builder builder = new AlertDialog.Builder(context);
        builder.setTitle("提示")
               .setMessage("这是一个示例对话框")
               .setPositiveButton("确定", new DialogInterface.OnClickListener() {
                    @Override
                    public void onClick(DialogInterface dialog, int which) {
                        // 点击确定按钮的处理逻辑
                    }
                })
               .setNegativeButton("取消", new DialogInterface.OnClickListener() {
                    @@Override
                    public void onClick(DialogInterface dialog, int which) {
                        // 点击取消按钮的处理逻辑
                    }
                });
        AlertDialog dialog = builder.create();
        dialog.show();
    }
}

这里,AlertDialog.Builder 相当于具体建造者,它逐步构建 AlertDialog(产品)的各个部分,如标题、消息内容、按钮等,而我们不需要关心 AlertDialog 内部复杂的创建和初始化过程,只需按照需求配置各个部件即可,最后通过 create 方法得到完整的对话框并展示。

五、应用场景

  1. 复杂对象构建:当需要创建的对象具有大量的属性、复杂的初始化逻辑,并且不同的属性组合会产生不同的功能或外观变体时,建造者模式非常适用。比如构建一辆汽车,涉及发动机、底盘、车身、内饰等多个复杂部件的选型与组装,使用建造者模式可以清晰地划分构建步骤,方便管理。
  2. 对象构建过程需要精细控制:如果对对象构建的顺序、步骤有严格要求,建造者模式能确保构建过程按照预定的流程进行。例如在建筑施工中,先打地基、再建主体、最后装修,通过指挥者精确安排建造者的工作顺序,保证建筑质量。
  3. 创建对象的逻辑频繁变化:当创建对象的逻辑需要经常调整,比如根据不同的市场需求,产品的配置、样式经常改变,建造者模式将构建逻辑封装在建造者和指挥者类中,修改时只需在相关类中进行,不影响客户端使用。

六、优缺点

优点

  1. 构建过程与表示分离:使得客户端不需要了解复杂对象的具体构建细节,降低了耦合度,客户端只需与指挥者和建造者的抽象接口交互,即使构建过程变化,也不影响客户端代码。
  2. 精细控制构建过程:通过指挥者可以精确安排构建步骤,满足不同的构建需求,确保复杂对象按照预期的方式构建,提高构建质量。
  3. 代码复用性高:抽象建造者和具体建造者类可以在多个地方复用,尤其是当有多种类似的复杂对象需要构建时,复用建造者类能节省开发时间。例如,不同风格的房屋建造可以复用基础的建造者类。
  4. 便于维护和扩展:当需要增加新的构建步骤、修改构建逻辑或创建新的复杂对象变体时,只需在建造者和指挥者类中操作,不会影响其他部分代码。如要给汽车增加自动驾驶功能模块,只需在相关建造者类中添加构建步骤。

缺点

  1. 增加代码复杂性:引入建造者模式会增加类的数量,包括抽象建造者、具体建造者、指挥者以及产品类,对于简单的对象创建场景,会使代码显得过于繁琐。
  2. 对开发人员要求较高:要求开发人员熟悉建造者模式的结构和原理,在设计和实现过程中需要合理规划各个角色的职责和交互,否则容易导致代码混乱,增加维护难度。

建造者模式为创建复杂对象提供了一种高效、灵活且易于维护的解决方案,虽然在简单场景下可能略显繁琐,但在应对复杂构建需求时能充分发挥其优势,提升软件的质量和开发效率。

在这里插入图片描述

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

如若内容造成侵权/违法违规/事实不符,请联系我们进行投诉反馈qq邮箱809451989@qq.com,一经查实,立即删除!

相关文章

2、pycharm常用快捷命令和配置【持续更新中】

1、常用快捷命令 Ctrl / 行注释/取消行注释 Ctrl Alt L 代码格式化 Ctrl Alt I 自动缩进 Tab / Shift Tab 缩进、不缩进当前行 Ctrl N 跳转到类 Ctrl 鼠标点击方法 可以跳转到方法所在的类 2、使用pip命令安装request库 命令&#xff1a;pip install requests 安装好了…

jenkins修改端口以及开机自启

修改Jenkins端口 方式一&#xff1a;通过配置文件修改&#xff08;以CentOS为例&#xff09; 找到配置文件&#xff1a;在CentOS系统中&#xff0c;通常可以在/etc/sysconfig/jenkins文件中修改Jenkins的配置。如果没有这个文件&#xff0c;也可以查看/etc/default/jenkins&…

破解密码

rhel8/centos8 重置 root 密码 方法 1 &#xff1a; rd.break 第 1 步 重启系统&#xff0c;在下图所示界面按 e 键 第2步 找到linux这行&#xff0c;末尾空格后 输入 rd.break 第3步 查看&#xff0c;可选步骤 这里 sysroot 是以只读的形式挂载的&#xff0c;所以要以可读可…

时间序列预测算法---LSTM

目录 一、前言1.1、深度学习时间序列一般是几维数据&#xff1f;每个维度的名字是什么&#xff1f;通常代表什么含义&#xff1f;1.2、为什么机器学习/深度学习算法无法处理时间序列数据?1.3、RNN(循环神经网络)处理时间序列数据的思路&#xff1f;1.4、RNN存在哪些问题? 二、…

从零用java实现 小红书 springboot vue uniapp (7)im 在线聊天功能 关注功能

前言 移动端演示 http://8.146.211.120:8081/#/ 前面的文章我们主要完成了笔记的点赞和收藏及留言功能 今天我们讲解点赞关注 im 聊天功能 关注 我们需要有一个关注的操作 这里我们复用个人中心页面 按钮会有三种形式 关注 取消关注 互相关注三种样式 <view class"gui…

PP模块部分BAPI函数

工艺路线 BAPI_ROUTING_CREATE 创建工艺路线 BAPI_ROUTING_EXISTENCE_CHECK 检查工艺路线是否存在 参考操作集 BAPI_REFSETOFOPERATIONS_CREATE 创建参考操作集 BAPI_REFSETOFOPR_EXISTENCE_CHK 检查参考操作集是否存在 计划订单 BAPI_PLANNEDORDER_CREATE 创建计划订单 BAPI…

Tomcat解析

架构图 核心功能 Tomcat是Apache开源的轻量级Java ServletServlet容器&#xff0c;其中一个Server&#xff08;Tomcat实例&#xff09;可以管理多个Service&#xff08;服务&#xff09;&#xff0c;一个Service包含多个Connector和一个Engine&#xff0c;负责管理请求到应用的…

【openGauss】正则表达式次数符号“{}“在ORACLE和openGauss中的差异

一、前言 正则作为一种常用的字符串处理方式&#xff0c;在各种开发语言&#xff0c;甚至数据库中&#xff0c;都有自带的正则函数。但是正则函数有很多标准&#xff0c;不同标准对正则表达式的解析方式不一样&#xff0c;本次在迁移一个ORACLE数据库到openGauss时发现了一个关…

C# 修改项目类型 应用程序程序改类库

初级代码游戏的专栏介绍与文章目录-CSDN博客 我的github&#xff1a;codetoys&#xff0c;所有代码都将会位于ctfc库中。已经放入库中我会指出在库中的位置。 这些代码大部分以Linux为目标但部分代码是纯C的&#xff0c;可以在任何平台上使用。 源码指引&#xff1a;github源…

DataV数据可视化

阿里云 DataV 是一个强大的数据可视化工具&#xff0c;可以帮助用户通过创建丰富的图表、仪表盘、地图和互动视图&#xff0c;将复杂的数据转化为易于理解和分析的可视化信息。DataV主要用于大数据和实时数据的展示&#xff0c;可以帮助企业和个人更直观地理解数据背后的含义&a…

STM32-笔记18-呼吸灯

1、实验目的 使用定时器 4 通道 3 生成 PWM 波控制 LED1 &#xff0c;实现呼吸灯效果。 频率&#xff1a;2kHz&#xff0c;PSC71&#xff0c;ARR499 利用定时器溢出公式 周期等于频率的倒数。故Tout 1/2KHZ&#xff1b;Ft 72MHZ PSC71&#xff08;喜欢设置成Ft的倍数&…

【20250101】Nature正刊:纯仿真强化学习得到外骨骼机器人的自适应控制策略

基本信息 论文标题&#xff1a;Experiment-free exoskeleton assistance via learning in simulation 发表期刊&#xff1a;Nature 发表时间&#xff1a;2024年6月12日 访问链接 论文&#xff1a;https://www.nature.com/articles/s41586-024-07382-4?fromPaywallRectrue 代…

【从零开始】11. LLaMA-Factory 微调 Qwen 模型(番外篇)

书接上回&#xff0c;在完成了 RAGChecker 测试后&#xff0c;离 RAG 应用真正发布还差最后一步 - 基础信息指令微调。考虑到模型还是需要具备一定程度的“自我认知”&#xff0c;因此需要将公司信息“嵌入”到模型里面的。为此&#xff0c;我选择了 LLaMA-Factory&#xff08;…

PowerShell 信息,请参阅 https......_Execution_Policies

文章目录 1. 问题分析2. 检查当前执行策略3. 解决方案&#xff1a;更改执行策略4. 若问题依然存在5. 注意事项 信息&#xff0c;请参阅 https:/go.microsoft.com/fwlink/?LinkID135170 中的 about _Execution_Policies。 所在位置 行:1 字符: 3. D:\Users\Documents\WindowsPo…

二、github基础

Github基础 备用github.com网站一、用户界面-Overview&#xff08;概览&#xff09;1用户信息2 导航栏3 热门仓库4 贡献设置5贡献活动6搜索和筛选7自定义收藏8贡献统计9最近活动10其他链接 二、用户界面-Repositories&#xff08;仓库&#xff09;1 libusb_stm322 savedata3 Fi…

C语言----指针

目录 1.概念 2.格式 3.指针操作符 4.初始化 1. 将普通变量的地址赋值给指针变量 a. 将数组的首地址赋值给指针变量 b. 将指针变量里面保存的地址赋值给另一个指针变量 5.指针运算 5.1算术运算 5.2 关系运算 指针的大小 总结&#xff1a; 段错误 指针修饰 1. con…

青少年编程与数学 02-006 前端开发框架VUE 01课题、VUE简介

青少年编程与数学 02-006 前端开发框架VUE 01课题、VUE简介 一、前端开发一、前端框架二、Vue.js三、应用场景四、区别五、学习资源六、应用示例说明&#xff1a; 课题摘要:本文介绍了前端开发框架Vue.js的基本概念和特性。Vue.js是一个渐进式JavaScript框架&#xff0c;用于构…

STM32单片机芯片与内部57 SPI 数据手册 寄存器

目录 一、SPI寄存器 1、SPI控制寄存器 1(SPI_CR1)(I2S模式下不使用) 2、SPI控制寄存器 2(SPI_CR2) 3、SPI 状态寄存器(SPI_SR) 4、SPI 数据寄存器(SPI_DR) 5、SPI CRC多项式寄存器(SPI_CRCPR)(I2S模式下不使用&#xff09; 6、SPI Rx CRC寄存器(SPI_RXCRCR)(I2S模式下不…

QT-------------自定义插件和库

以下是一个使用 Qt 实现图表交互操作的示例&#xff0c;涵盖了自定义图表视图类、不同类型的柱状图和饼图等内容。 实现思路 自定义图表视图类&#xff1a;创建一个从 QChartView 派生的自定义类&#xff0c;用于处理图表的交互操作。主窗口设计初始化&#xff1a;在主窗口中…

【Python】闭包

闭包&#xff08;Closure&#xff09;是指一个函数记住了并可以访问它的词法作用域&#xff08;lexical scope&#xff09;&#xff0c;即使这个函数在词法作用域之外执行。 闭包其实就是延伸了作用域的函数&#xff0c;包括被延伸函数主体中引用的非全局变量和局部变量。这些…