当前位置: 首页 > news >正文

【设计模式】建造者模式

建造者模式(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 对象的 MealBuilderBuilderPatternDemo 类使用 MealBuilder 来创建一个 Meal

 

 

建造者模式的 UML 图

步骤 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

相关文章:

【设计模式】建造者模式

建造者模式&#xff08;Builder Pattern&#xff09;使用多个简单的对象一步一步构建成一个复杂的对象。这种类型的设计模式属于创建型模式&#xff0c;它提供了一种创建对象的最佳方式。 一个 Builder 类会一步一步构造最终的对象。该 Builder 类是独立于其他对象的。 介绍 …...

网络安全---正则回溯

目录 一、题目引入 二、举出回溯例子进行分析 第一步&#xff1a; 正则往前匹配 第二步&#xff1a;匹配到头 第三步&#xff1a;往回匹配 第四步&#xff1a;直到分号结束 &#xff08;匹配上&#xff09; 原因&#xff1a; 三、进入正题一&#xff08;分析题型&#…...

压测秒杀场景常见问题

很多人在做秒杀场景的压测时&#xff0c;经常出现以下两个问题&#xff1a; 1&#xff0c;用自己的笔记本电脑瞬间发起1000个请求 2&#xff0c;没有使用虚拟ip&#xff08;发起的请求都是同样的一个ip&#xff09; 其实现在很多人在做秒杀压测的时候&#xff0c;都会遇到这两…...

【python】【sql】格式化注意事项

如果需要格式化表名到 sql 语句&#xff0c;sql 引擎是不支持的。 所以表名需要用字符串格式化&#xff0c;但其他参数最好用 sql 自带的格式&#xff0c;这样就不用去调一些细节&#xff0c;比如字符串的值是否要带引号之类的。 比如&#xff1a; cur.execute(SELECT {0} FR…...

leetcode做题笔记71

给你一个字符串 path &#xff0c;表示指向某一文件或目录的 Unix 风格 绝对路径 &#xff08;以 / 开头&#xff09;&#xff0c;请你将其转化为更加简洁的规范路径。 在 Unix 风格的文件系统中&#xff0c;一个点&#xff08;.&#xff09;表示当前目录本身&#xff1b;此外…...

啥是 Python?学了他能干嘛?

最近在学 python&#xff0c;真心感觉这玩意太牛了&#xff0c;你能想到&#xff0c;想不到的事情他都能做&#xff0c;前两天也是总结了一下 python 的特点&#xff0c;分享给大家看看~ 与君共勉 历史篇 1989年圣诞节&#xff0c;当大家都在忙着包装礼物&#xff0c;享受节日…...

百日筑基篇——Pandas学习三(pyhton入门八)

百日筑基篇——Pandas学习三&#xff08;pyhton入门八&#xff09; 文章目录 前言一、数据排序二、字符串处理三、数据合并方法1. merge方法2. concat方法 四、分组数据统计五、数据重塑1. stack2. pivot 总结 前言 上一篇文章介绍了一下pandas库中的一些函数&#xff0c;而本…...

【Android Framework系列】第10章 PMS之Hook实现广播的调用

1 前言 前面章节我们学习了【Android Framework系列】第4章 PMS原理我们了解了PMS原理&#xff0c;【Android Framework系列】第9章 AMS之Hook实现登录页跳转我们知道AMS可以Hook拦截下来实现未注册Activity页面的跳转&#xff0c;本章节我们来尝试一下HookPMS实现广播的发送。…...

Mysql锁实战

mysql版本&#xff1a;8.0.32 通过实战验证mysql的Record lock 与 Gap lock原理 准备工作 设置隔离级别为&#xff1a;RR&#xff0c;以及innodb状态输出锁相关信息 show variables like %innodb_status_output_locks%; show variables like %isolation%;set global innodb_…...

HCIP-OpenStack发放云主机

1、云中的概念 在云平台注册了一个账号&#xff0c;这个账号对于云平台来说&#xff0c;就是一个租户或者一个项目。 租户/项目&#xff08;tenant/project&#xff09;&#xff0c;租户就是项目的意思。主机聚合就是主机组的意思。 region&#xff08;区域&#xff09;&…...

时序预测 | MATLAB基于扩散因子搜索的GRNN广义回归神经网络时间序列预测(多指标,多图)

时序预测 | MATLAB基于扩散因子搜索的GRNN广义回归神经网络时间序列预测(多指标,多图) 目录 时序预测 | MATLAB基于扩散因子搜索的GRNN广义回归神经网络时间序列预测(多指标,多图)效果一览基本介绍程序设计学习小结参考资料效果一览...

Vulhub之Apache HTTPD 换行解析漏洞(CVE-2017-15715)

Apache HTTPD是一款HTTP服务器&#xff0c;它可以通过mod_php来运行PHP网页。其2.4.0~2.4.29版本中存在一个解析漏洞&#xff0c;在解析PHP时&#xff0c;1.php\x0A将被按照PHP后缀进行解析&#xff0c;导致绕过一些服务器的安全策略。 1、docker-compose build、docker-compo…...

ARTS 挑战打卡的第7天 --- Ubuntu中的WindTerm如何设置成中文,并且关闭shell中Tab键声音(Tips)

前言 &#xff08;1&#xff09;Windterm是一个非常优秀的终端神器。关于他的下载我就不多说了&#xff0c;网上很多。今天我就分享一个国内目前没有找到的这方面的资料——Ubuntu中的WindTerm如何设置成中文&#xff0c;并且关闭shell中Tab键声音。 将WindTerm设置成中文 &…...

Oracle之执行计划

1、查看执行计划 EXPLAIN PLAN FOR SELECT * FROM temp_1 a ; SELECT * FROM TABLE(DBMS_XPLAN.DISPLAY); 2、执行计划说明 2.1、执行顺序 根据缩进来判断&#xff0c;缩进最多的最先执行&#xff1b;&#xff08;缩进相同时&#xff0c;最上面的最先执行&#xff09; 2.2…...

【Vue框架】菜单栏权限的使用与显示

前言 在 【Vue框架】Vue路由配置 中的getters.js里&#xff0c;可以看到有一个应用程序的状态&#xff08;变量&#xff09;叫 permission_routes&#xff0c;这个就是管理前端菜单栏的状态。具体代码的介绍&#xff0c;都以注释的形式来说明。 1、modules\permission.js 1…...

案例研究|大福中国通过JumpServer满足等保合规和资产管理双重需求

“大福中国为了满足安全合规要求引入堡垒机产品&#xff0c;在对比了传统型堡垒机后&#xff0c;发现JumpServer使用部署更加灵活&#xff0c;功能特性丰富&#xff0c;能够较好地满足公司在等保合规和资产管理方面的双重需求。” ——大福&#xff08;中国&#xff09;有限公…...

大数据课程I4——Kafka的零拷贝技术

文章作者邮箱&#xff1a;yugongshiyesina.cn 地址&#xff1a;广东惠州 ▲ 本章节目的 ⚪ 掌握Kafka的零拷贝技术&#xff1b; ⚪ 了解常规的文件传输过程&#xff1b; 一、常规的网络传输原理 表面上一个很简单的网络文件输出的过程&#xff0c;在OS底层&…...

红日ATT&CK VulnStack靶场(三)

网络拓扑 web阶段 1.扫描DMZ机器端口 2.进行ssh和3306爆破无果后访问web服务 3.已知目标是Joomla&#xff0c;扫描目录 4.有用的目录分别为1.php 5.configuration.php~中泄露了数据库密码 6.administrator为后台登录地址 7.直接连接mysql 8.找到管理员表&#xff0c;密码加密了…...

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 设计&#xff1a;小艾 审核&#xff1a;丁奇、李浩 编辑&#xff1a;宇亭 作者&#xff1a;王若添 中国科学技术大学-软件工程-在读硕士、StoneDB 内核研发实习生 performance_schema 简介 MySQL 启动后会自动创建四…...

OpenClaw飞书集成:Kimi-VL-A3B-Thinking多模态机器人配置教程

OpenClaw飞书集成&#xff1a;Kimi-VL-A3B-Thinking多模态机器人配置教程 1. 为什么选择OpenClaw飞书Kimi-VL-A3B-Thinking组合 去年我在处理团队知识库时&#xff0c;发现一个痛点&#xff1a;每当同事在飞书群聊里分享产品截图或设计稿时&#xff0c;总要手动保存图片再上传…...

最通俗的 LDA 线性判别分析教程

&#x1f525; 最通俗的 LDA 线性判别分析教程&#xff08;本科生/研究生都能懂&#xff09; 大家好&#xff0c;今天我们来彻底吃透LDA&#xff08;线性判别分析&#xff09;。 这是机器学习、模式识别、数据降维里必考、必用、必懂的算法&#xff0c;面试、比赛、写论文都高频…...

大模型实习内推:这些技能必须具备

现在95%的大模型实习岗位&#xff0c;都不是让你去从头“创造”一个GPT-5&#xff0c;而是让你基于现有的模型&#xff0c;去做各种“下游”工作。什么意思呢&#xff1f;大家想象中的大模型实习&#xff0c;可能是这样的&#xff1a;一排排A100/H100在你面前闪烁&#xff0c;你…...

避开FMC的那些‘坑’:正点原子F429开发板驱动TFT屏和SDRAM的实战避坑指南

正点原子F429开发板FMC接口深度优化&#xff1a;TFT屏与SDRAM的高效驱动实践 硬件连接的关键细节 在FMC接口应用中&#xff0c;硬件连接的正确性直接决定了后续软件调试的成败。许多开发者往往在硬件连接阶段就埋下了隐患&#xff0c;导致后期出现各种难以排查的问题。 地址…...

Linux网络驱动实验

直接参考【正点原子】I.MX6U嵌入式Linux驱动开发指南V1.81 本文仅作为个人笔记使用&#xff0c;方便进一步记录自己的实践总结。 网络驱动是 linux 里面驱动三巨头之一&#xff0c;linux 下的网络功能非常强大&#xff0c;嵌入式 linux 中也常常用到网络功能。前面我们已经讲过…...

BUCK变换器断续模式实战:从公式推导到MATLAB仿真验证(附代码)

BUCK变换器断续模式实战&#xff1a;从公式推导到MATLAB仿真验证&#xff08;附代码&#xff09; 在电力电子领域&#xff0c;BUCK变换器作为最基础的降压型拓扑结构&#xff0c;其工作模式的理解直接影响着电源设计的可靠性。许多初学者往往对断续模式(DCM)的特性感到困惑——…...

2026年毕业答辩前AI率还超标怎么办?临时补救的4个方案

答辩三天前&#xff0c;导师发来消息&#xff1a;你的论文AI率38%&#xff0c;这个数字不行&#xff0c;重新处理一下。 三天&#xff0c;这不是慢慢来的时间。当时我确实慌了&#xff0c;但最后还是处理下来了。现在把当时的紧急补救方案整理出来&#xff0c;万一有人需要。 …...

C++27反射工具链现状全景图(2024Q3):Boost.PFR停更、cpp-reflect弃坑、std::reflect成为唯一工业级选择?

第一章&#xff1a;C27静态反射的标准化演进与战略意义C27静态反射&#xff08;Static Reflection&#xff09;正从实验性提案走向核心语言特性&#xff0c;其标准化进程标志着C元编程范式的根本性跃迁。不同于C20的std::is_same_v等类型特征或C23的std::type_identity_t&#…...

MacOS极简部署OpenClaw:5分钟连接Phi-3-vision-128k-instruct模型

MacOS极简部署OpenClaw&#xff1a;5分钟连接Phi-3-vision-128k-instruct模型 1. 为什么选择OpenClawPhi-3组合 去年第一次听说AI能直接操作我的电脑时&#xff0c;我本能地感到不安——让一个云端模型控制本地文件系统&#xff1f;这听起来就像把家门钥匙交给陌生人。直到发…...

COMSOL后处理技巧:精确计算动态接触面积

1. 为什么动态接触面积计算这么重要&#xff1f; 在工程仿真中&#xff0c;接触问题无处不在。比如手机按键的触感反馈、汽车刹车片的磨损分析、机械密封件的性能评估&#xff0c;这些场景都需要精确掌握两个物体在运动过程中的实际接触面积。我做过一个橡胶密封圈的案例&#…...