4、设计模式之建造者模式(Builder)
一、什么是建造者模式
建造者模式是一种创建型设计模式,也叫生成器模式。
定义:封装一个复杂对象构造过程,并允许按步骤构造。
解释:就是将复杂对象的创建过程拆分成多个简单对象的创建过程,并将这些简单对象组合起来构建出复杂对象。
二、角色组成
产品类(Product):表示被创建的复杂对象。它通常包含多个部分或者组成,并由具体的建造者逐步构建而成。
抽象建造者类(Builder):定义了建造复杂对象所需要的各个部分的创建方法。它通常包括多个构建方法和一个返回产品的方法。
具体建造者类(ConcreteBuilder):实现Builder接口,并提供各个部分或者组成的构建方法。
指挥者类(Director):负责控制建造者的构建顺序,指挥建造者如何构建复杂对象。
三、优缺点
优点:
灵活:可以分步骤地构建复杂对象,使得构建过程更加灵活。
解耦:可以隔离复杂对象的创建和使用,客户端不必关心对象的创建细节。
易扩展:增加新的具体建造者很方便,可以扩展构建器功能,符合开闭原则。
缺点:
增加工作量:需要额外的代码来创建和管理具体建造者类,增加了程序员的工作量。
效率低:相比于其他创建型模式,在运行时效率较低,特别是对象太复杂时。
四、应用场景
4.1 生活场景
盒饭套餐:顾客可以选择不同的菜,服务员按照顾客的要求,将这些菜组合起来,最终构建出一个完整的套餐。
盖房子:需要分多个阶段进行,比如准备材料、打地基、盖围墙…。建造者模式可以将房屋的建造分解成多个步骤,每个步骤对应一个具体的建造者,最终由包工头(指导者)来调用不同的建造者,完成整个房子的建造。
4.2 java场景
StringBuilder:能够动态地构建字符串。
Stream API:将集合类转为stream流,通过一系列的中间操作和终止操作来生成最终结果。
Lombok的@Builder注解:一个注解就可以生成建造者模式的代码。
五、代码实现
肯德徳都吃过吧,里面有很多的套餐。假设套餐主要由汉堡、薯条和饮料三种组成,每个组件都有不同种类和大小,并且每个套餐的组合方式也不同。下面以肯德徳套餐为例,解释建造者模式。
产品类:Meal
抽象建造者类:MealBuilder
具体建造者类:BeefBurgerMealBuilder、ChickenMealBuilder、ShrimpMealBuilder
指挥者类:MealDirector
5.1 产品类(Product)
/*** * 1.产品类(Product)*/
@Data
public class Meal {//汉堡包private String burger;//薯条private String fries;//饮料private String drink;
}
5.2 抽象建造者(Builder)
/*** * 2.抽象建造者(Builder)*/
public abstract class MealBuilder {protected Meal meal=new Meal();//构建汉堡public abstract void buildBurger();//构建薯条public abstract void buildFries();//构建饮料public abstract void buildDrink();public Meal getMeal(){return meal;}
}
5.3 具体构建者(ConcreteBuilder)
/**** 3.具体建造者(ConcreteBuilder):鸡肉汉堡套餐*/
public class ChickenMealBuilder extends MealBuilder{@Overridepublic void buildBurger() {meal.setBurger("鸡肉汉堡");}@Overridepublic void buildFries() {meal.setFries("中份薯条");}@Overridepublic void buildDrink() {meal.setDrink("大杯果汁");}
}
/*** * 3.具体建造者(ConcreteBuilder):牛肉汉堡套餐*/
public class BeefBurgerMealBuilder extends MealBuilder {@Overridepublic void buildBurger() {meal.setBurger("牛肉汉堡");}@Overridepublic void buildFries() {meal.setFries("大份薯条");}@Overridepublic void buildDrink() {meal.setDrink("中杯可乐");}
}
/*** * 3.具体建造者(ConcreteBuilder):虾肉汉堡套餐*/
public class ShrimpMealBuilder extends MealBuilder {@Overridepublic void buildBurger() {meal.setBurger("虾肉汉堡");}@Overridepublic void buildFries() {meal.setFries("小份薯条");}@Overridepublic void buildDrink() {meal.setDrink("大杯芬达");}
}
5.4 指导者(Director)
/*** * 4.指导者(Director)*/
public class MealDirector {private MealBuilder mealBuilder;public void setMealBuilder(MealBuilder mealBuilder){this.mealBuilder=mealBuilder;}public Meal getMeal(){return mealBuilder.getMeal();}//制作套餐public void constructMeal(){mealBuilder.buildBurger();mealBuilder.buildFries();mealBuilder.buildDrink();}
}
5.5 testBuilder
/*** * 建造者模式测试类*/
@SpringBootTest
public class TestBuilder {@Testvoid testBuilder(){//创建指导者MealDirector director=new MealDirector();//执导建造牛肉套餐director.setMealBuilder(new BeefBurgerMealBuilder());director.constructMeal();Meal meal = director.getMeal();System.out.println("牛肉套餐:"+meal.toString());//鸡肉套餐director.setMealBuilder(new ChickenMealBuilder());director.constructMeal();Meal meal2 = director.getMeal();System.out.println("鸡肉套餐:"+meal2.toString());//虾肉套餐director.setMealBuilder(new ShrimpMealBuilder());director.constructMeal();Meal meal3 = director.getMeal();System.out.println("虾肉套餐:"+meal3.toString());}
}
根据不同的需求,建造者模式可以构造出不同的套餐对象。每个套餐的构建过程都由不同的建造者实现,在构建过程中可定制相应的属性。最终,因为套餐的构建过程和表示分离,所以同样的构建过程可以创建出不同的表示。
六、总结
使用场景:
当需要创建一些特定的对象,但是它们拥有共同的组成部分时,比如:一个房子可以由个个部件:框架、墙、窗户等,这些部件可以组合起来构造完整的房子。
当对象的构建过程比较复杂且需要多个步骤时,例如,创建一份电子商务订单需要多个步骤,如选择商品、填写地址和支付等,这些步骤可以被分别封装成为订单构建器中的不同方法。
当需要创建一些特定类型的对象,例如复杂的数据结构或配置对象时,这在编写配置文件解析器以及通用数据结构如二叉树等时很有用。
建造者模式也可以被用于通过更高级的方式来构建复杂对象,例如:序列化和反序列化。
与抽象工厂模式的区别:
抽象工厂模式强调的是产品族的创建,即相关的产品一起被创建出来,而建造者模式强调的是一个复杂对象的创建,即它的各个部分逐步被创建出来。
相关文章:

4、设计模式之建造者模式(Builder)
一、什么是建造者模式 建造者模式是一种创建型设计模式,也叫生成器模式。 定义:封装一个复杂对象构造过程,并允许按步骤构造。 解释:就是将复杂对象的创建过程拆分成多个简单对象的创建过程,并将这些简单对象组合起来…...

网工内推 | 上市公司网工,IE认证优先,最高18K*13薪,包吃住
01 深圳市宝腾互联科技有限公司 招聘岗位:网络工程师 职责描述: 1、是整个数据中心的网络技术及安全问题的负责人,确保数据中心业务的正常进行; 2、负责规划、设计、搭建、维护数据中心的网络环境,确保IDC /云平台&a…...
SQL Server 技术100问?
这些问题旨在帮助SQL Server的管理员和开发人员深入理解数据库管理系统的核心概念和技术,从而更好地进行数据库设计、性能优化、安全管理等工作。 SQL Server的最新版本有哪些新特性?如何在SQL Server中创建一个新的数据库?如何在SQL Server…...

鸿蒙不再适合JS语言开发
ArkTS是鸿蒙生态的应用开发语言。它在保持TypeScript(简称TS)基本语法风格的基础上,对TS的动态类型特性施加更严格的约束,引入静态类型。同时,提供了声明式UI、状态管理等相应的能力,让开发者可以以更简洁、…...

Python环境搭建 -- Python与PyCharm安装
一、Python安装 我们先找到Python的官方网站,在浏览器中搜索Python即可,然后进入Python官网 点击Downloads,选择对应匹配的操作系统 点进去之后,Python的版本分为稳定的版本和前置版本,前置的版本就是还没有发行的版本…...

OSCP靶场--Astronaut
OSCP靶场–Astronaut 考点(1.CVE-2021-21425getshell 2.suid php提权) 1.nmap扫描 ┌──(root㉿kali)-[~/Desktop] └─# nmap -sV -sC -p- 192.168.163.12 --min-rate 2500 Starting Nmap 7.92 ( https://nmap.org ) at 2024-03-14 01:24 EDT Nmap scan report for 192.16…...
Springboot 使用【过滤器】实现在请求到达 Controller 之前修改请求体参数和在结果返回之前修改响应体
文章目录 前情提要解决方案自定义 HttpServletRequest 包装类 RequestWrapper自定义 HttpServletResponse 包装类 ResponseWrapper自定义过滤器 MiddlewareFilter配置过滤器注解配置类 编写 Controller 测试 前情提要 在项目中需要使用过滤器 在请求调用 Controller 方法前修改…...
Unity 3D常用的数据结构
目录 数组使用场景 ArrayList数组ArrayList的缺点 List\<T\>数组List\<T\>有以下3点好处 链表链表与数组的不同之处链表的优势数组和链表的应用场景 LinkedList\<T\>C#中内置的双向链表LinkedList使用场景 队列(Queue\<T\>)和栈…...
h5唤起微信小程序
wx-open-launch-weapp 就用这个 开放标签属于自定义标签,Vue会给予未知标签的警告,可通过配置Vue.config.ignoredElements [wx-open-launch-weapp] 来忽略Vue对开放标签的检查。 sdk授权。 调试打开时iOS会弹窗 noPermissionJsApi: [],confi…...

面向对象(精髓)变继承关系为组和关系(_Decorator模式)
在软件开发中,设计模式是解决常见问题的可重用解决方案。在面向对象编程中,继承和组合是两种常用的代码复用方式。然而,随着软件需求的不断变化,我们需要更灵活的设计方式来应对不断变化的需求。在本文中,我们将讨论从…...

MES系统在智能生产中的重要作用
在未来智能制造的发展趋势中,制造执行系统(MES)作为关键技术和工具,扮演着至关重要的角色。随着科技的不断进步和制造业的数字化转型,MES的地位将愈发凸显,对于企业实现智能化生产、提高效率、降低成本具有…...
2024.3.13每日一题
LeetCode 最大二进制奇数 题目链接:2864. 最大二进制奇数 - 力扣(LeetCode) 题目描述 给你一个 二进制 字符串 s ,其中至少包含一个 1 。 你必须按某种方式 重新排列 字符串中的位,使得到的二进制数字是可以由该组…...

YOLOv5 | 涨点复现!YOLOv5添加BiFPN有效提升目标检测精度
目录 🚀🚀🚀订阅专栏,更新及时查看不迷路🚀🚀🚀 介绍: BiFPN 代码实现 ⭐欢迎大家订阅我的专栏一起学习⭐ 🚀🚀🚀订阅专栏,更新及…...
【Nut3】nuxt.config.ts项目nuxt配置文件介绍
简言 记录下nuxt3的nuxt.config.ts文件的介绍和使用。 Nuxt Configuration nuxt.config.ts Nuxt可以通过一个单独的nuxt.config文件进行简单配置。 配置文件创建 nuxt.config文件的扩展名可以是.js、.ts或.mjs。 然后默认导出全局函数defineNuxtConfig的返回值,…...
区块链技术的革命性影响
1. 区块链技术的基本原理: 区块链是一种去中心化的分布式数据库技术,通过不断增长的记录(块)构成一个链式结构。每个区块包含了交易数据的加密信息以及上一个区块的哈希值,从而形成了不可篡改的交易记录。这种去中心化…...

多线程(volatile)
volatile的功能 保证内存可见性禁止指令重排序 内存可见性 简单的理解 两(多)个线程同时针对一个变量进行操作, 一个线程读, 一个线程修改, 此时读到的值不一定是修改过后的值 即读线程没有感知到变量的变化 (其实是 编译器/JVM 对于代码在多线程情况下的优化进行了误判) 从 J…...

蓝桥杯 填空 卡片
蓝桥杯 填空题 卡片 解题思路: 我们只需要消耗完卡片的个数即可。 代码示例: #include<bits/stdc.h> using namespace std; int a[10]; bool isEnd(){for(int i0;i<10;i){if(a[i]-1)return false;}return true; } bool getN(int x){while(x){i…...

ELK介绍使用
文章目录 一、ELK介绍二、Elasticsearch1. ElasticSearch简介:2. Elasticsearch核心概念3. Elasticsearch安装4. Elasticsearch基本操作1. 字段类型介绍2. 索引3. 映射4. 文档 5. Elasticsearch 复杂查询 三、LogStash1. LogStash简介2. LogStash安装 四、kibana1. …...

【UE5】非持枪状态蹲姿移动的动画混合空间
项目资源文末百度网盘自取 在BlendSpace文件夹中单击右键选择动画(Animation)中的混合空间(Blend Space) ,选择SK_Female_Skeleton,命名为BS_NormalCrouch 打开BS_NormalCrouch 水平轴表示角色的方向,命名为Direction,方向的最…...
Windows C++ TCP开发(使用select函数以及设置非阻塞/Reuse属性)
1、select官方函数说明: 语法 C int WSAAPI select([in] int nfds,[in, out] fd_set *readfds,[in, out] fd_set *writefds,[in, out] fd_set *exceptfds,[in] const timeval *timeout );参数 [in] nfds 已忽略。 包含 nf…...

智慧工地云平台源码,基于微服务架构+Java+Spring Cloud +UniApp +MySql
智慧工地管理云平台系统,智慧工地全套源码,java版智慧工地源码,支持PC端、大屏端、移动端。 智慧工地聚焦建筑行业的市场需求,提供“平台网络终端”的整体解决方案,提供劳务管理、视频管理、智能监测、绿色施工、安全管…...
1688商品列表API与其他数据源的对接思路
将1688商品列表API与其他数据源对接时,需结合业务场景设计数据流转链路,重点关注数据格式兼容性、接口调用频率控制及数据一致性维护。以下是具体对接思路及关键技术点: 一、核心对接场景与目标 商品数据同步 场景:将1688商品信息…...

2021-03-15 iview一些问题
1.iview 在使用tree组件时,发现没有set类的方法,只有get,那么要改变tree值,只能遍历treeData,递归修改treeData的checked,发现无法更改,原因在于check模式下,子元素的勾选状态跟父节…...

Nuxt.js 中的路由配置详解
Nuxt.js 通过其内置的路由系统简化了应用的路由配置,使得开发者可以轻松地管理页面导航和 URL 结构。路由配置主要涉及页面组件的组织、动态路由的设置以及路由元信息的配置。 自动路由生成 Nuxt.js 会根据 pages 目录下的文件结构自动生成路由配置。每个文件都会对…...
如何为服务器生成TLS证书
TLS(Transport Layer Security)证书是确保网络通信安全的重要手段,它通过加密技术保护传输的数据不被窃听和篡改。在服务器上配置TLS证书,可以使用户通过HTTPS协议安全地访问您的网站。本文将详细介绍如何在服务器上生成一个TLS证…...
WEB3全栈开发——面试专业技能点P2智能合约开发(Solidity)
一、Solidity合约开发 下面是 Solidity 合约开发 的概念、代码示例及讲解,适合用作学习或写简历项目背景说明。 🧠 一、概念简介:Solidity 合约开发 Solidity 是一种专门为 以太坊(Ethereum)平台编写智能合约的高级编…...

dify打造数据可视化图表
一、概述 在日常工作和学习中,我们经常需要和数据打交道。无论是分析报告、项目展示,还是简单的数据洞察,一个清晰直观的图表,往往能胜过千言万语。 一款能让数据可视化变得超级简单的 MCP Server,由蚂蚁集团 AntV 团队…...
高效线程安全的单例模式:Python 中的懒加载与自定义初始化参数
高效线程安全的单例模式:Python 中的懒加载与自定义初始化参数 在软件开发中,单例模式(Singleton Pattern)是一种常见的设计模式,确保一个类仅有一个实例,并提供一个全局访问点。在多线程环境下,实现单例模式时需要注意线程安全问题,以防止多个线程同时创建实例,导致…...
PAN/FPN
import torch import torch.nn as nn import torch.nn.functional as F import mathclass LowResQueryHighResKVAttention(nn.Module):"""方案 1: 低分辨率特征 (Query) 查询高分辨率特征 (Key, Value).输出分辨率与低分辨率输入相同。"""def __…...

【VLNs篇】07:NavRL—在动态环境中学习安全飞行
项目内容论文标题NavRL: 在动态环境中学习安全飞行 (NavRL: Learning Safe Flight in Dynamic Environments)核心问题解决无人机在包含静态和动态障碍物的复杂环境中进行安全、高效自主导航的挑战,克服传统方法和现有强化学习方法的局限性。核心算法基于近端策略优化…...