设计模式之创建者模式
文章目录
- 一、介绍
- 二、应用
- 三、案例
- 1. 麦当劳1+1随心配
- 2. 代码演示
- 3. 演示结果
- 四、优缺点
- 五、送给读者
一、介绍
建造者模式(Builder Pattern)属于创建型设计模式,很多博客文章的对它的作用解释为用于将复杂对象的创建过程与其细节表示分离。但对于初学者来说,这句话难免有点晦涩难懂,何为复杂对象?何为创建过程,何为细节表示?
复杂对象:一个对象中的成员属性出了基本数据类型及其对应的封装类型,还包含有其他类型对象。例如:在对象A中包含对象B的引用,对象B中又包含对象C的引用。
创建过程:一个对象的实例化和初始化过程。如new一个对象后再调用其set方法为其初始化。
细节表示:在对一个对象初始化时,通过set方法表示其创建的细节。说白了,细节表示就是该对象的成员变量。
在一般情况下,我们要创建一个完整的对象时,往往是通过两个步骤完成:①实例化(即new一个对象);②初始化(即调用set方法对其属性赋值)。这是一种创建过程与细节表示耦合的情况。即:一个对象的实例化和初始化过程就表示为其创建过程;而在初始化过程中通过set方法我们又了解到了其内部属性(即细节表示)。
而在建造者模式中,我们只需要通过一个对象的建造者(Builder)所提供的方法向其描述对象的细节,该然后该建造者通过其核心方法build()将对象实例化并补充其细节。这就是建造者的核心思想。
二、应用
- java中的
StringBuilder类。我们通过其提供的各种重载的append()方法,描述一个字符串的细节,最后通过toString()方法获得String实例。 - OkHttp中应用了大量的建造者模式。如创建请求客户端时,使用
OkHttpClient的内部类Builder来描述请求的细节,然后通过build()方法获得一个OkHttpClient实例。
三、案例
1. 麦当劳1+1随心配
我们以麦当劳随心配1+1套餐为例,当用户选择该套餐时,该套餐规定选择一个任意主食 + 一个任意冷饮。如下图所示
-
选择主食

-
选择冷饮

添加到购物车后,我们可以看到该套餐详情

2. 代码演示
-
新建套餐抽象接口
Meal,以及实现该接口的随心配1+1套餐SuiXinPeiMealpublic interface Meal {// 套餐价格Float getCost();// 套餐详情void order(); }public class SuiXinPeiMeal implements Meal{// 主食private Food food;// 冷饮private ColdDrink coldDrink;// 省略get、set方法...// 套餐价格@Overridepublic Float getCost() {return 5F;}// 套餐详情@Overridepublic void order() {System.out.println("随心配1+1套餐:");System.out.println("主食:" + food.getName() + ",单价:" + food.getCost());System.out.println("冷饮:" + coldDrink.getName() + ",单价:" + coldDrink.getCost());System.out.println("套餐价格:" + getCost());} } -
新建一个随心配1+1套餐的创建者
SuiXinPeiMealBuilder:public class SuiXinPeiMealBuilder {private Food food;private ColdDrink coldDrink;// 向套餐中添加主食public void addFood(Food food) {this.food = food;}// 向套餐中添加冷饮public void addColdDrink(ColdDrink coldDrink) {this.coldDrink = coldDrink;}// 创建套餐public Meal build() {if (food == null) {throw new RuntimeException("请选择一个主食");}if (coldDrink == null) {throw new RuntimeException("请选择一个冷饮");}SuiXinPeiMeal meal = new SuiXinPeiMeal();meal.setFood(food);meal.setColdDrink(coldDrink);return meal;} } -
新建单品抽象接口
SingleProductpublic interface SingleProduct {// 单品名称String getName();// 单品价格Float getCost(); } -
新建主食抽象接口
Food、及其实现类Chicken鸡块、Fries薯条、Hamburger汉堡public interface Food extends SingleProduct { }public class Chicken implements Food{@Overridepublic String getName() {return "鸡块";}@Overridepublic Float getCost() {return 13F;} }public class Fries implements Food{@Overridepublic String getName() {return "薯条";}@Overridepublic Float getCost() {return 10F;} }public class Hamburger implements Food {@Overridepublic String getName() {return "汉堡";}@Overridepublic Float getCost() {return 15F;} } -
新建冷饮抽象接口
ColdDrink、及其实现类CocaCola可乐、NoSugarCola无糖可乐、Sprite雪碧public interface ColdDrink extends SingleProduct { }public class CocaCola implements ColdDrink{@Overridepublic String getName() {return "可乐";}@Overridepublic Float getCost() {return 3.8F;} }public class NoSugarCola implements ColdDrink {@Overridepublic String getName() {return "无糖可乐";}@Overridepublic Float getCost() {return 5.0F;} }public class Sprite implements ColdDrink {@Overridepublic String getName() {return "雪碧";}@Overridepublic Float getCost() {return 8F;} } -
在
main()方法中进行套餐模拟public static void main(String[] args) {// 套餐:鸡块+可乐SuiXinPeiMealBuilder builder1 = new SuiXinPeiMealBuilder();// 选择鸡块builder1.addFood(new Chicken());// 选择可口可乐builder1.addColdDrink(new CocaCola());// 创建订单Meal meal1 = builder1.build();// 输出订单详情meal1.order();System.out.println("==============================================");// 套餐:汉堡+雪碧SuiXinPeiMealBuilder builder2 = new SuiXinPeiMealBuilder();builder2.addFood(new Hamburger());builder2.addColdDrink(new Sprite());Meal meal2 = builder2.build();meal2.order(); }
3. 演示结果
运行上述代码,结果如下

四、优缺点
- 优点
- 对象的创建过程与其细节表示分离,即解耦。
- 缺点:
- 产生多余的建造者Builder类,且每当添加一种套餐,就需要多写一个对应的套餐建造者类。
- 建造者与对象之间耦合,当修改对象结构时,建造者也要修改。
- 可读性相对较差。
五、送给读者
- 在非必要的情况下,业务代码中不建议使用该设计模式,没有性能上的优化却导致可读性变差,属于炫技型设计模式。
- 如果本文对你有所帮助,别忘了安排博主一顿麦当劳随心配1+1套餐哦。
纸上得来终觉浅,绝知此事要躬行。
————————我是万万岁,我们下期再见————————
相关文章:
设计模式之创建者模式
文章目录 一、介绍二、应用三、案例1. 麦当劳11随心配2. 代码演示3. 演示结果 四、优缺点五、送给读者 一、介绍 建造者模式(Builder Pattern)属于创建型设计模式,很多博客文章的对它的作用解释为用于将复杂对象的创建过程与其细节表示分离。但对于初学者来说&…...
Java之包,权限修饰符,final关键字详解
包 2.1 包 包在操作系统中其实就是一个文件夹。包是用来分门别类的管理技术,不同的技术类放在不同的包下,方便管理和维护。 在IDEA项目中,建包的操作如下: 包名的命名规范: 路径名.路径名.xxx.xxx // 例如ÿ…...
“深入解析JVM:Java虚拟机内部原理揭秘“
标题:深入解析JVM:Java虚拟机内部原理揭秘 摘要:本文将深入探讨Java虚拟机(JVM)的内部原理,包括JVM的架构、运行时数据区域、垃圾回收机制以及即时编译器等重要组成部分。通过对JVM内部原理的解析…...
Mac下Jmeter安装及基本使用
本篇文章只是简单的介绍下Jmeter的下载安装和最基本使用 1、初识Jmeter 前一段时间客户端app自测的过程中,有偶现请求某个接口返回数据为空的问题,领导让我循环100次请求这个接口,看看有没有结果为空的问题。听同事说有Jmeter的专业测试工具…...
云计算与边缘计算:加速数字化转型的关键驱动力
云计算和边缘计算技术正以惊人的速度改变着企业的业务和基础架构。这些先进的技术为企业带来了灵活性、可扩展性和成本效益的优势,重新定义了业务运作的方式。 云计算是通过互联网将计算资源提供给用户的一种服务模式。通过云计算,企业可以将应用程序、…...
TheGem主题 - 创意多用途和高性能WooCommerce WordPress主题/网站
TheGem主题概述 – 适合所有人的TheGem 作为设计元素、样式和功能的终极 Web 构建工具箱而设计和开发,TheGem主题将帮助您在几分钟内构建一个令人印象深刻的高性能网站,而无需触及一行代码。不要在编码上浪费时间,探索你的创造力!…...
Pytorch-day10-模型部署推理-checkpoint
模型部署&推理 模型部署模型推理 我们会将PyTorch训练好的模型转换为ONNX 格式,然后使用ONNX Runtime运行它进行推理 1、ONNX ONNX( Open Neural Network Exchange) 是 Facebook (现Meta) 和微软在2017年共同发布的,用于标准描述计算图的一种格式…...
vue使用websocket
建立websocket.js // 信息提示 import { Message } from element-ui // 引入用户id import { getTenantId, getAccessToken } from /utils/auth// websocket地址 var url ws://192.168.2.20:48081/websocket/message // websocket实例 var ws // 重连定时器实例 var tt // w…...
jmeter入门:接口压力测试全解析
一.对接口压力测试 1.配置 1.添加线程组(参数上文有解释 这里不介绍) 2.添加取样器 不用解释一看就知道填什么。。。 3.添加头信息(否则请求头对不上) 也不用解释。。。 4.配置监听器 可以尝试使用这几个监听器。 2.聚合结果…...
go、java、.net、C#、nodejs、vue、react、python程序问题进群咨询
1、面试辅导 2、程序辅导 3、一对一腾讯会议辅导 3、业务逻辑辅导 4、各种bug帮你解决。 5、培训小白 6、顺利拿到offer...
树莓派4B最新系统Bullseye 64 bit使用xrdp远程桌面黑屏卡顿问题
1、树莓派换源 打开源文件 sudo nano /etc/apt/sources.list注释原来的,更换为清华源 deb https://mirrors.tuna.tsinghua.edu.cn/debian/ bullseye main contrib non-free deb https://mirrors.tuna.tsinghua.edu.cn/debian/ bullseye-updates main contrib no…...
EasyExcel入门介绍及工具类,网络下载excel
前言:在这里分享自己第一次使用EasyExcel并且编写工具类,且在接口中支持excel文件下载的一系列流程,包含所有前后端(JSJAVA)完整代码,可以根据自己需要自行提取,仅供参考。 一.引入EasyExcel依赖…...
【HarmonyOS北向开发】-04 ArkTS开发语言-ArkTS基础知识
飞书原文档:Docs...
【Alibaba中间件技术系列】「RocketMQ技术专题」小白专区之领略一下RocketMQ基础之最!
应一些小伙伴们的私信,希望可以介绍一下RocketMQ的基础,那么我们现在就从0开始,进入RocketMQ的基础学习及概念介绍,为学习和使用RocketMQ打好基础! RocketMQ是一款快速地、可靠地、分布式、容易使用的消息中间件&#…...
营销活动:提升小程序的用户活跃度的关键
在现今竞争激烈的商业环境中,小程序已成为企业私域营销的重要工具之一。然而,拥有一个小程序并不足以保证用户的活跃度。营销活动作为推动用户参与的有效方式,对于提升小程序的用户活跃度起着至关重要的作用。本文将深入探讨营销活动在提升小…...
Neo4j之CALL基础
CALL 语句用于调用 Neo4j 数据库中预定义的函数、过程或者自定义的函数。它是用来执行一些特定操作或计算的重要工具。以下是一些常用的 CALL 语句示例和解释: 调用内置函数: CALL db.labels()这个示例中,调用了内置函数 db.labels() 来获取…...
【TypeScript】元组
元组(Tuple)是 TypeScript 中的一种特殊数据类型,它允许你定义一个固定数量和类型的元素组合。元组可以包含不同类型的数据,每个数据的类型在元组中都是固定的。以下是 TypeScript 中元组的基本用法和特点: // 声明一…...
数据仓库一分钟
数据分层 一、数据运营层:ODS(Operational Data Store) “面向主题的”数据运营层,也叫ODS层,是最接近数据源中数据的一层,数据源中的数据,经过抽取、洗净、传输,也就说传说中的 ETL…...
提升Python代理程序性能的终极解决方案:缓存、连接池和并发
在开发Python代理程序时,优化性能是至关重要的。本文将为你介绍一套终极解决方案,通过缓存、连接池和并发处理等技术,极大地提升Python代理程序的效率和稳定性。 游戏国内地更换虚拟含ip地址数据库地区 1.缓存技术 缓存是 .0-*-696ES2 0一…...
CSS和AJAX阶段学习记录
1、AJAX的工作原理: 如图所示,工作原理可以分为以下几步: 网页中发生一个事件(页面加载、按钮点击) 由 JavaScript 创建 XMLHttpRequest 对象 XMLHttpRequest 对象向 web 服务器发送请求 服务器处理该请求 服务器将响应…...
C++初阶-list的底层
目录 1.std::list实现的所有代码 2.list的简单介绍 2.1实现list的类 2.2_list_iterator的实现 2.2.1_list_iterator实现的原因和好处 2.2.2_list_iterator实现 2.3_list_node的实现 2.3.1. 避免递归的模板依赖 2.3.2. 内存布局一致性 2.3.3. 类型安全的替代方案 2.3.…...
HTML 列表、表格、表单
1 列表标签 作用:布局内容排列整齐的区域 列表分类:无序列表、有序列表、定义列表。 例如: 1.1 无序列表 标签:ul 嵌套 li,ul是无序列表,li是列表条目。 注意事项: ul 标签里面只能包裹 li…...
如何将联系人从 iPhone 转移到 Android
从 iPhone 换到 Android 手机时,你可能需要保留重要的数据,例如通讯录。好在,将通讯录从 iPhone 转移到 Android 手机非常简单,你可以从本文中学习 6 种可靠的方法,确保随时保持连接,不错过任何信息。 第 1…...
3403. 从盒子中找出字典序最大的字符串 I
3403. 从盒子中找出字典序最大的字符串 I 题目链接:3403. 从盒子中找出字典序最大的字符串 I 代码如下: class Solution { public:string answerString(string word, int numFriends) {if (numFriends 1) {return word;}string res;for (int i 0;i &…...
3-11单元格区域边界定位(End属性)学习笔记
返回一个Range 对象,只读。该对象代表包含源区域的区域上端下端左端右端的最后一个单元格。等同于按键 End 向上键(End(xlUp))、End向下键(End(xlDown))、End向左键(End(xlToLeft)End向右键(End(xlToRight)) 注意:它移动的位置必须是相连的有内容的单元格…...
SQL慢可能是触发了ring buffer
简介 最近在进行 postgresql 性能排查的时候,发现 PG 在某一个时间并行执行的 SQL 变得特别慢。最后通过监控监观察到并行发起得时间 buffers_alloc 就急速上升,且低水位伴随在整个慢 SQL,一直是 buferIO 的等待事件,此时也没有其他会话的争抢。SQL 虽然不是高效 SQL ,但…...
【C++特殊工具与技术】优化内存分配(一):C++中的内存分配
目录 一、C 内存的基本概念 1.1 内存的物理与逻辑结构 1.2 C 程序的内存区域划分 二、栈内存分配 2.1 栈内存的特点 2.2 栈内存分配示例 三、堆内存分配 3.1 new和delete操作符 4.2 内存泄漏与悬空指针问题 4.3 new和delete的重载 四、智能指针…...
Selenium常用函数介绍
目录 一,元素定位 1.1 cssSeector 1.2 xpath 二,操作测试对象 三,窗口 3.1 案例 3.2 窗口切换 3.3 窗口大小 3.4 屏幕截图 3.5 关闭窗口 四,弹窗 五,等待 六,导航 七,文件上传 …...
Axure 下拉框联动
实现选省、选完省之后选对应省份下的市区...
ZYNQ学习记录FPGA(一)ZYNQ简介
一、知识准备 1.一些术语,缩写和概念: 1)ZYNQ全称:ZYNQ7000 All Pgrammable SoC 2)SoC:system on chips(片上系统),对比集成电路的SoB(system on board) 3)ARM:处理器…...
