设计模式之创建者模式
文章目录
- 一、介绍
- 二、应用
- 三、案例
- 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套餐SuiXinPeiMeal
public 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;} }
-
新建单品抽象接口
SingleProduct
public 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 服务器发送请求 服务器处理该请求 服务器将响应…...
Android自定义View知识体系
View的概念、作用和基本属性 View是Android中的基本UI组件,用于构建用户界面。它可以是按钮、文本框、图像等可见元素,也可以是容器,用于组织其他View。View的作用是展示数据和接收用户的输入。它可以显示文本、图片、动画等内容,…...
Springboot 自定义 Mybatis拦截器,实现 动态查询条件SQL自动组装拼接(玩具)
前言 ps:最近在参与3100保卫战,战况很激烈,刚刚打完仗,来更新一下之前写了一半的博客。 该篇针对日常写查询的时候,那些动态条件sql 做个简单的封装,自动生成(抛砖引玉,搞个小玩具&a…...
Go 1.21新增的 slices 包详解(三)
Go 1.21新增的 slices 包提供了很多和切片相关的函数,可以用于任何类型的切片。 slices.Max 定义如下: func Max[S ~[]E, E cmp.Ordered](x S) E 返回 x 中的最大值,如果 x 为空,则 panic。对于浮点数 E, 如果有元素为 NaN&am…...
Python 在logging.config.dictConfig()日志配置方式下,使用自定义的Handler处理程序
文章目录 一、基于 RotatingFileHandler 的自定义处理程序二、基于 TimedRotatingFileHandler 的自定义处理程序 Python logging模块的基本使用、进阶使用详解 Python logging.handlers模块,RotatingFileHandler、TimedRotatingFileHandler 处理器各参数详细介绍 …...
Anaconda, Python, Jupyter和PyCharm介绍
目录 1 Anaconda, Python, Jupyter和PyCharm介绍 2 macOS通过Anaconda安装Python, Jupyter和PyCharm 3 使用终端创建虚拟环境并安装PyTorch 4 安装PyCharm并导入Anaconda虚拟环境 5 Windows操作系统下Anaconda与PyCharm安装 6 通过 Anaconda Navigator 创建 TensorFlow 虚…...
axios 各种方式的请求 示例
GET请求 示例一: 服务端代码 GetMapping("/f11") public String f11(Integer pageNum, Integer pageSize) {return pageNum " : " pageSize; }前端代码 <template><div class"home"><button click"getFun1…...
基于开源模型搭建实时人脸识别系统(四):人脸质量
续人脸识别实战之基于开源模型搭建实时人脸识别系统(三):人脸关键点、对齐模型概览与模型选型_CodingInCV的博客-CSDN博客 不论对于静态的人脸识别还是动态的人脸识别,我们都会面临一个问题,就是输入的人脸图像的质量可…...
【开发笔记】ubuntu部署指定版本的前后端运行环境(npm nodejs mysql)
目录 1 背景2 环境要求3 部署流程3.1 npm的安装3.2 nodejs的安装3.3 MySQL的安装 4 可能的问题 1 背景 在远程服务器上的Ubuntu系统中,部署指定版本的前后端项目的运行环境 2 环境要求 npm 9.5.1Nodejs v18.16.1MySQL 8.0.33 3 部署流程 3.1 npm的安装 通过安…...
用于优化开关性能的集成异质结二极管的4H-SiC沟道MOSFET
标题:4H-SiC Trench MOSFET with Integrated Heterojunction Diode for Optimizing Switching Performance 摘要 本研究提出了一种新型的4H-SiC沟道MOSFET,其在栅槽底部集成了异质结二极管(HJD-TMOS),并通过TCAD模拟进…...
优化个人博客总结
前面学习完怎么搭建个人博客,后面要做的就是排版优化自己的博客了,今天通过教程学习到了然后更爱美化其中的效果,还通过改写代码来带到基本的效果展示,同时也把最开始学习的计算速成课的笔记输出在上面,这也是一个很好…...
建站之星模板好吗/纵横seo
1.occupancy grid作用是什么...
网站建设销售前景/百度热搜榜怎么打开
转载请标明出处:http://blog.csdn.net/xx326664162/article/details/67640509 文章出自:薛瑄的博客 Dagger2 系列: Dagger2 入门详解(一) Scope 看这一篇就够了——Dagger2 (二) 1、Scope 到…...
wordpress禁用react/郑州网站推广优化
一、首先说一下,Hadoop有三种运行模式。 第一个是独立(或本地)运行模式:无需运行任何守护进程,所有程序都在一个同一个JVM上执行。 第二个是伪分布模式:Hadoop守护进程运行在本地机器上,模拟一个小规模的集群。 第三个…...
武汉网站建设武汉/百度搜索下载app
下面是小凰凰的简介,看下吧! 💗人生态度:珍惜时间,渴望学习,热爱音乐,把握命运,享受生活 💗学习技能:网络 -> 云计算运维 -> python全栈( 当前正在学习…...
广州最专业的网站建设/成都官网seo费用
引用自: asp.net获取网站路径 http://hi.baidu.com/zhangfengbang/blog/item/5f99d74b0ce661f883025cbc.html HttpRequest 成员 http://msdn.microsoft.com/zh-cn/library/system.web.httprequest_members(vVS.80).aspx ASP.NET获取网站根目录的url的函数࿰…...
网站建设公司一站通系统简单/湖南企业seo优化
quickhybrid 项目地址:quickhybrid/quickhybrid 简介: 快速混合开发框架,JSBridge 提供核心 Android、iOS 功能。多平台 API 支撑,部分兼容浏览器 更多:作者 提 Bug 标签: quickhybrid- 快速混合…...