【设计模式】建造者模式
建造者模式(Builder Pattern)使用多个简单的对象一步一步构建成一个复杂的对象。这种类型的设计模式属于创建型模式,它提供了一种创建对象的最佳方式。
一个 Builder 类会一步一步构造最终的对象。该 Builder 类是独立于其他对象的。
介绍
意图:将一个复杂的构建与其表示相分离,使得同样的构建过程可以创建不同的表示。
主要解决:主要解决在软件系统中,有时候面临着"一个复杂对象"的创建工作,其通常由各个部分的子对象用一定的算法构成;由于需求的变化,这个复杂对象的各个部分经常面临着剧烈的变化,但是将它们组合在一起的算法却相对稳定。
何时使用:一些基本部件不会变,而其组合经常变化的时候。
如何解决:将变与不变分离开。
关键代码:建造者:创建和提供实例,导演:管理建造出来的实例的依赖关系。
应用实例: 1、去肯德基,汉堡、可乐、薯条、炸鸡翅等是不变的,而其组合是经常变化的,生成出所谓的"套餐"。 2、JAVA 中的 StringBuilder。
优点:
- 分离构建过程和表示,使得构建过程更加灵活,可以构建不同的表示。
- 可以更好地控制构建过程,隐藏具体构建细节。
- 代码复用性高,可以在不同的构建过程中重复使用相同的建造者。
缺点:
- 如果产品的属性较少,建造者模式可能会导致代码冗余。
- 建造者模式增加了系统的类和对象数量。
使用场景: 1、需要生成的对象具有复杂的内部结构。 2、需要生成的对象内部属性本身相互依赖。
建造者模式在创建复杂对象时非常有用,特别是当对象的构建过程涉及多个步骤或参数时。它可以提供更好的灵活性和可维护性,同时使得代码更加清晰可读。
注意事项:与工厂模式的区别是:建造者模式更加关注与零件装配的顺序。
实现
我们假设一个快餐店的商业案例,其中,一个典型的套餐可以是一个汉堡(Burger)和一杯冷饮(Cold drink)。汉堡(Burger)可以是素食汉堡(Veg Burger)或鸡肉汉堡(Chicken Burger),它们是包在纸盒中。冷饮(Cold drink)可以是可口可乐(coke)或百事可乐(pepsi),它们是装在瓶子中。
我们将创建一个表示食物条目(比如汉堡和冷饮)的 Item 接口和实现 Item 接口的实体类,以及一个表示食物包装的 Packing 接口和实现 Packing 接口的实体类,汉堡是包在纸盒中,冷饮是装在瓶子中。
然后我们创建一个 Meal 类,带有 Item 的 ArrayList 和一个通过结合 Item 来创建不同类型的 Meal 对象的 MealBuilder。BuilderPatternDemo 类使用 MealBuilder 来创建一个 Meal。
步骤 1
创建一个表示食物条目和食物包装的接口。
Item.java
public interface Item {public String name();public Packing packing();public float price();
}
Packing.java
public interface Packing {public String pack();
}
步骤 2
创建实现 Packing 接口的实体类。
Wrapper.java
public class Wrapper implements Packing {@Overridepublic String pack() {return "Wrapper";}
}
Bottle.java
public class Bottle implements Packing {@Overridepublic String pack() {return "Bottle";}
}
步骤 3
创建实现 Item 接口的抽象类,该类提供了默认的功能。
Burger.java
public abstract class Burger implements Item {@Overridepublic Packing packing() {return new Wrapper();}@Overridepublic abstract float price();
}
ColdDrink.java
public abstract class ColdDrink implements Item {@Overridepublic Packing packing() {return new Bottle();}@Overridepublic abstract float price();
}
步骤 4
创建扩展了 Burger 和 ColdDrink 的实体类。
VegBurger.java
public class VegBurger extends Burger {@Overridepublic float price() {return 25.0f;}@Overridepublic String name() {return "Veg Burger";}
}
ChickenBurger.java
public class ChickenBurger extends Burger {@Overridepublic float price() {return 50.5f;}@Overridepublic String name() {return "Chicken Burger";}
}
Coke.java
public class Coke extends ColdDrink {@Overridepublic float price() {return 30.0f;}@Overridepublic String name() {return "Coke";}
}
Pepsi.java
public class Pepsi extends ColdDrink {@Overridepublic float price() {return 35.0f;}@Overridepublic String name() {return "Pepsi";}
}
步骤 5
创建一个 Meal 类,带有上面定义的 Item 对象。
Meal.java
import java.util.ArrayList;
import java.util.List;public class Meal {private List<Item> items = new ArrayList<Item>(); public void addItem(Item item){items.add(item);}public float getCost(){float cost = 0.0f;for (Item item : items) {cost += item.price();} return cost;}public void showItems(){for (Item item : items) {System.out.print("Item : "+item.name());System.out.print(", Packing : "+item.packing().pack());System.out.println(", Price : "+item.price());} }
}
步骤 6
创建一个 MealBuilder 类,实际的 builder 类负责创建 Meal 对象。
MealBuilder.java
public class MealBuilder {public Meal prepareVegMeal (){Meal meal = new Meal();meal.addItem(new VegBurger());meal.addItem(new Coke());return meal;} public Meal prepareNonVegMeal (){Meal meal = new Meal();meal.addItem(new ChickenBurger());meal.addItem(new Pepsi());return meal;}
}
步骤 7
BuiderPatternDemo 使用 MealBuilder 来演示建造者模式(Builder Pattern)。
BuilderPatternDemo.java
public class BuilderPatternDemo {public static void main(String[] args) {MealBuilder mealBuilder = new MealBuilder();Meal vegMeal = mealBuilder.prepareVegMeal();System.out.println("Veg Meal");vegMeal.showItems();System.out.println("Total Cost: " +vegMeal.getCost());Meal nonVegMeal = mealBuilder.prepareNonVegMeal();System.out.println("\n\nNon-Veg Meal");nonVegMeal.showItems();System.out.println("Total Cost: " +nonVegMeal.getCost());}
}
步骤 8
执行程序,输出结果:
Veg Meal
Item : Veg Burger, Packing : Wrapper, Price : 25.0
Item : Coke, Packing : Bottle, Price : 30.0
Total Cost: 55.0Non-Veg Meal
Item : Chicken Burger, Packing : Wrapper, Price : 50.5
Item : Pepsi, Packing : Bottle, Price : 35.0
Total Cost: 85.5
相关文章:
【设计模式】建造者模式
建造者模式(Builder Pattern)使用多个简单的对象一步一步构建成一个复杂的对象。这种类型的设计模式属于创建型模式,它提供了一种创建对象的最佳方式。 一个 Builder 类会一步一步构造最终的对象。该 Builder 类是独立于其他对象的。 介绍 …...
网络安全---正则回溯
目录 一、题目引入 二、举出回溯例子进行分析 第一步: 正则往前匹配 第二步:匹配到头 第三步:往回匹配 第四步:直到分号结束 (匹配上) 原因: 三、进入正题一(分析题型&#…...
压测秒杀场景常见问题
很多人在做秒杀场景的压测时,经常出现以下两个问题: 1,用自己的笔记本电脑瞬间发起1000个请求 2,没有使用虚拟ip(发起的请求都是同样的一个ip) 其实现在很多人在做秒杀压测的时候,都会遇到这两…...
【python】【sql】格式化注意事项
如果需要格式化表名到 sql 语句,sql 引擎是不支持的。 所以表名需要用字符串格式化,但其他参数最好用 sql 自带的格式,这样就不用去调一些细节,比如字符串的值是否要带引号之类的。 比如: cur.execute(SELECT {0} FR…...
leetcode做题笔记71
给你一个字符串 path ,表示指向某一文件或目录的 Unix 风格 绝对路径 (以 / 开头),请你将其转化为更加简洁的规范路径。 在 Unix 风格的文件系统中,一个点(.)表示当前目录本身;此外…...
啥是 Python?学了他能干嘛?
最近在学 python,真心感觉这玩意太牛了,你能想到,想不到的事情他都能做,前两天也是总结了一下 python 的特点,分享给大家看看~ 与君共勉 历史篇 1989年圣诞节,当大家都在忙着包装礼物,享受节日…...
百日筑基篇——Pandas学习三(pyhton入门八)
百日筑基篇——Pandas学习三(pyhton入门八) 文章目录 前言一、数据排序二、字符串处理三、数据合并方法1. merge方法2. concat方法 四、分组数据统计五、数据重塑1. stack2. pivot 总结 前言 上一篇文章介绍了一下pandas库中的一些函数,而本…...
【Android Framework系列】第10章 PMS之Hook实现广播的调用
1 前言 前面章节我们学习了【Android Framework系列】第4章 PMS原理我们了解了PMS原理,【Android Framework系列】第9章 AMS之Hook实现登录页跳转我们知道AMS可以Hook拦截下来实现未注册Activity页面的跳转,本章节我们来尝试一下HookPMS实现广播的发送。…...
Mysql锁实战
mysql版本:8.0.32 通过实战验证mysql的Record lock 与 Gap lock原理 准备工作 设置隔离级别为:RR,以及innodb状态输出锁相关信息 show variables like %innodb_status_output_locks%; show variables like %isolation%;set global innodb_…...
HCIP-OpenStack发放云主机
1、云中的概念 在云平台注册了一个账号,这个账号对于云平台来说,就是一个租户或者一个项目。 租户/项目(tenant/project),租户就是项目的意思。主机聚合就是主机组的意思。 region(区域)&…...
时序预测 | MATLAB基于扩散因子搜索的GRNN广义回归神经网络时间序列预测(多指标,多图)
时序预测 | MATLAB基于扩散因子搜索的GRNN广义回归神经网络时间序列预测(多指标,多图) 目录 时序预测 | MATLAB基于扩散因子搜索的GRNN广义回归神经网络时间序列预测(多指标,多图)效果一览基本介绍程序设计学习小结参考资料效果一览...
Vulhub之Apache HTTPD 换行解析漏洞(CVE-2017-15715)
Apache HTTPD是一款HTTP服务器,它可以通过mod_php来运行PHP网页。其2.4.0~2.4.29版本中存在一个解析漏洞,在解析PHP时,1.php\x0A将被按照PHP后缀进行解析,导致绕过一些服务器的安全策略。 1、docker-compose build、docker-compo…...
ARTS 挑战打卡的第7天 --- Ubuntu中的WindTerm如何设置成中文,并且关闭shell中Tab键声音(Tips)
前言 (1)Windterm是一个非常优秀的终端神器。关于他的下载我就不多说了,网上很多。今天我就分享一个国内目前没有找到的这方面的资料——Ubuntu中的WindTerm如何设置成中文,并且关闭shell中Tab键声音。 将WindTerm设置成中文 &…...
Oracle之执行计划
1、查看执行计划 EXPLAIN PLAN FOR SELECT * FROM temp_1 a ; SELECT * FROM TABLE(DBMS_XPLAN.DISPLAY); 2、执行计划说明 2.1、执行顺序 根据缩进来判断,缩进最多的最先执行;(缩进相同时,最上面的最先执行) 2.2…...
【Vue框架】菜单栏权限的使用与显示
前言 在 【Vue框架】Vue路由配置 中的getters.js里,可以看到有一个应用程序的状态(变量)叫 permission_routes,这个就是管理前端菜单栏的状态。具体代码的介绍,都以注释的形式来说明。 1、modules\permission.js 1…...
案例研究|大福中国通过JumpServer满足等保合规和资产管理双重需求
“大福中国为了满足安全合规要求引入堡垒机产品,在对比了传统型堡垒机后,发现JumpServer使用部署更加灵活,功能特性丰富,能够较好地满足公司在等保合规和资产管理方面的双重需求。” ——大福(中国)有限公…...
大数据课程I4——Kafka的零拷贝技术
文章作者邮箱:yugongshiyesina.cn 地址:广东惠州 ▲ 本章节目的 ⚪ 掌握Kafka的零拷贝技术; ⚪ 了解常规的文件传输过程; 一、常规的网络传输原理 表面上一个很简单的网络文件输出的过程,在OS底层&…...
红日ATT&CK VulnStack靶场(三)
网络拓扑 web阶段 1.扫描DMZ机器端口 2.进行ssh和3306爆破无果后访问web服务 3.已知目标是Joomla,扫描目录 4.有用的目录分别为1.php 5.configuration.php~中泄露了数据库密码 6.administrator为后台登录地址 7.直接连接mysql 8.找到管理员表,密码加密了…...
JavaScript之BOM+window对象+定时器+location,navigator,history对象
一.BOM概述 BOM即浏览器对象模型,它提供了独立于内容而与窗口进行交互的对象 BOM的顶级对象是window 二.window对象的常见事件 1.窗口加载事件window.onload window.onload function(){} 或者 window.addEventListener("onload" , function(){}); window.onlo…...
为MySQL新增一张performance_schema表 | StoneDB 技术分享会 #4
StoneDB开源地址 https://github.com/stoneatom/stonedb 设计:小艾 审核:丁奇、李浩 编辑:宇亭 作者:王若添 中国科学技术大学-软件工程-在读硕士、StoneDB 内核研发实习生 performance_schema 简介 MySQL 启动后会自动创建四…...
环境光遮蔽(Ambient Occlusion):揭秘那个让虚拟世界“有重量感“的阴影魔法
一、一个让我"开窍"的老木匠故事 我有个朋友是传统家具的修复师,他给我讲过一个让我至今难忘的故事。他说他刚入行时跟着一位 70 多岁的老木匠师父学习——师父让他做的第一件事不是雕花、不是榫卯——而是"看阴影"——这个看似奇怪的训练改变了…...
Arduino PWM转4-20mA工业电流信号:二阶滤波与V/I转换电路设计
1. 项目概述:从PWM到工业标准电流信号在工业自动化、过程控制和传感器领域,4-20 mA电流环是一个几乎无处不在的标准。它用4 mA代表测量值的下限(如0C),20 mA代表上限(如100C),这种设…...
写论文的神助攻!好用的AI写作辅助软件,逻辑清晰质量高
作为一名刚完成毕业论文的过来人,我太懂写论文的痛苦了 —— 选题迷茫、文献浩如烟海、框架混乱、逻辑不清、反复修改、查重降重反复折腾... 直到我发现了这套 AI 写作工具组合,简直是论文写作的 "开挂神器",效率直接拉满ÿ…...
Keil µVision链接器错误204解决方案
1. 问题现象与背景解析最近在使用Keil Vision进行嵌入式开发时,不少工程师遇到了一个令人头疼的链接器错误。具体表现为编译时出现"FATAL ERROR 204: INVALID KEYWORD"的致命错误,错误位置指向链接器控制文件中的特定行。这个问题在C166和C51两…...
别让依赖毁了你的实验:记一次Vision Mamba复现中causal_conv1d与mamba-ssm的版本“打架”事件
Vision Mamba复现实战:破解依赖冲突的工程化解决方案在深度学习项目的复现过程中,依赖管理往往是最容易被忽视却又最常导致问题的环节。最近在复现Vision Mamba模型时,我遭遇了一场典型的Python依赖"战争"——causal_conv1d与mamba…...
别再把大模型当搜索框了:一文讲透 LLM 的基本原理、能力边界与局限性
写在前面很多人把大语言模型当成“会聊天的搜索引擎”,结果一上线就遇到幻觉、口径不稳、上下文丢失、成本失控。真正理解 LLM,要先抓住一句话:它是基于 Transformer 的概率生成模型,核心能力来自海量预训练、上下文学习与后训练对…...
Sora 2 GIF导出速度提升300%?20年多媒体架构师亲授GPU加速转码链路(CUDA 12.4 + cuVID硬编实测)
更多请点击: https://kaifayun.com 第一章:Sora 2 GIF导出方法概览 Sora 2 并非 OpenAI 官方发布的模型,当前(截至2024年)并无名为“Sora 2”的公开产品。因此,所谓“Sora 2 GIF导出”实为社区对视频生成工…...
3步零基础掌握星露谷物语SMAPI模组加载器:高效管理你的模组世界
3步零基础掌握星露谷物语SMAPI模组加载器:高效管理你的模组世界 【免费下载链接】SMAPI The modding API for Stardew Valley. 项目地址: https://gitcode.com/gh_mirrors/smap/SMAPI SMAPI(Stardew Valley Modding API)是星露谷物语官…...
D2DX如何让暗黑破坏神2在4K显示器上流畅运行:5个关键技术解析
D2DX如何让暗黑破坏神2在4K显示器上流畅运行:5个关键技术解析 【免费下载链接】d2dx D2DX is a complete solution to make Diablo II run well on modern PCs, with high fps and better resolutions. 项目地址: https://gitcode.com/gh_mirrors/d2/d2dx 当…...
3步搞定B站缓存视频转换:m4s转MP4的终极解决方案
3步搞定B站缓存视频转换:m4s转MP4的终极解决方案 【免费下载链接】m4s-converter 一个跨平台小工具,将bilibili缓存的m4s格式音视频文件合并成mp4 项目地址: https://gitcode.com/gh_mirrors/m4/m4s-converter 你是否曾经在B站缓存了珍贵的视频&a…...
