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());}
}

根据不同的需求,建造者模式可以构造出不同的套餐对象。每个套餐的构建过程都由不同的建造者实现,在构建过程中可定制相应的属性。最终,因为套餐的构建过程和表示分离,所以同样的构建过程可以创建出不同的表示。

六、总结
使用场景:

当需要创建一些特定的对象,但是它们拥有共同的组成部分时,比如:一个房子可以由个个部件:框架、墙、窗户等,这些部件可以组合起来构造完整的房子。
当对象的构建过程比较复杂且需要多个步骤时,例如,创建一份电子商务订单需要多个步骤,如选择商品、填写地址和支付等,这些步骤可以被分别封装成为订单构建器中的不同方法。
当需要创建一些特定类型的对象,例如复杂的数据结构或配置对象时,这在编写配置文件解析器以及通用数据结构如二叉树等时很有用。
建造者模式也可以被用于通过更高级的方式来构建复杂对象,例如:序列化和反序列化。
与抽象工厂模式的区别:

抽象工厂模式强调的是产品族的创建,即相关的产品一起被创建出来,而建造者模式强调的是一个复杂对象的创建,即它的各个部分逐步被创建出来。

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.mzph.cn/news/742626.shtml

如若内容造成侵权/违法违规/事实不符,请联系多彩编程网进行投诉反馈email:809451989@qq.com,一经查实,立即删除!

相关文章

使用 ReclaiMe Pro 进行 RAIDZ 数据恢复

天津鸿萌科贸发展有限公司是 ReclaiMe Pro 数据恢复软件授权代理商。 ZFS 是一个开源文件系统,主要用于 FreeNAS 和 NAS4Free 存储系统。在开发 ZFS 时,主要目标是可靠性,这是通过写时复制、冗余元数据、日志等不同功能来实现的。ZFS 使用自…

修改表结构

目录 修改表结构 创建数据表插入数据 修改已有列 修改 member 表的 name 列的定义 为表增加列 增加一个 address 列,这个列上不设置默认值 增加一个 sex 列,这个列上设置默认值 删除表中的列 删除 sex 列 Oracle从入门到总裁:​​​​​​https…

SpringSecurity两种验证方式及调用流程

一、HttpBasic方式 <security:http-basic/> 二、Formlogin方式 <security:form-login login-page"/userLogin" /> 三、SpringSecurity执行流程

【LeetCode】升级打怪之路 Day 18:二叉树题型 —— 树的深度、高度、路经

今日题目&#xff1a; 104. 二叉树的最大深度111. 二叉树的最小深度110. 平衡二叉树257. 二叉树的所有路径112. 路径总和 目录 Problem 1&#xff1a;树的深度LC 104. 二叉树的最大深度 【easy】LC 111. 二叉树的最小深度 【易错】 Problem 2&#xff1a;树的高度LC 110. 平衡二…

工具推荐:有哪些工具可以搭建本地知识库?

大家是否心头藏着一个个的记录本&#xff0c;里面写满了工作日常、业务过程、个人想法等等&#xff0c;但是随着这个记录本日渐丰满&#xff0c;寻找特定信息的难度也在逐渐增大。如果有一个空间&#xff0c;既像你的记录本一样方便记录&#xff0c;又可以快速检索&#xff0c;…

19113133262(微信同号)2024年环境能源与全球市场营销国际学术会议(ICEEGM 2024)

2024年环境能源与全球市场营销国际学术会议&#xff08;ICEEGM 2024) 会议主题: (主题包括但不限于, 更多主题请咨询会务组苏老师) 节能技术 煤矿工程与技术 能源存储技术 可再生能源 热能与动力工程 能源工程与环境工程 可再生能源技术和系统 能源安全和清洁利用 矿…

1688平台最关键的接口接入实例|获得1688商品详情| 按关键字搜索商品| 按图搜索1688商品(拍立淘)| 获得淘口令真实url

参数说明 通用参数说明 version:API版本key:调用key,测试key:test_api_keyapi_name:API类型[item_get,item_search]cache:[yes,no]默认yes&#xff0c;将调用缓存的数据&#xff0c;速度比较快result_type:[json,xml,serialize,var_export]返回数据格式&#xff0c;默认为jsonl…

springboot的maven多模块如何混淆jar包

springboot的maven多模块如何混淆jar包 一.简介二. 示例2.1 基本配置2.2 结果 三. 错误3.1 错误13.2 错误2 四. 参考文章 前言 这是我在这个网站整理的笔记,有错误的地方请指出&#xff0c;关注我&#xff0c;接下来还会持续更新。 作者&#xff1a;神的孩子都在歌唱 一.简介 …

[Linux][CentOs][Mysql]基于Linux-CentOs7.9系统安装并配置开机自启Mysql-8.0.28数据库

目录 一、准备工作&#xff1a;获取安装包和相应工具 &#xff08;一&#xff09;所需安装包 &#xff08;二&#xff09;安装包下载链接 &#xff08;三&#xff09;在服务器上创建文件夹并上传安装包 二、安装MySql &#xff08;一&#xff09;删除系统自带的mariadb …

华为三层交换机:ACL的基本实验

实验要求&#xff1a; PC1不允许访问PC3&#xff0c;PC3可以访问PC1 分析问题&#xff1a; PC1不允许访问PC3&#xff0c;问题中含有“目标地址”则我们需要设置目标地址&#xff0c;这样基本ACL是不行的&#xff0c;必须使用高级ACL [sw1]acl ? INTEGER<2000-2999>…

发那科数控机床FanucCNC(NCGuide)仿真模拟器配置和数据采集测试

开发日记3.12 此篇用于记录发那科数控机床(Fanuc CNC)采集程序开发中&#xff0c;用虚拟机做测试时&#xff0c;虚拟机的配置和使用以支持采集软件开发和测试。 配置虚拟机使用仿真软件 下载VMware15 「链接&#xff1a;https://pan.xunlei.com/s/VNsl9Gmb14ANBiiNlsT7vA2LA…

选择格行随身WiFi代理的八大理由:揭秘其无可比拟的优势!2024适合普通人的靠谱创业项目!

在竞争激烈的创投圈中中&#xff0c;格行随身WiFi以其独特的八大优势脱颖而出&#xff0c;成为创业者的首选品牌。那么&#xff0c;它究竟凭借什么成为了创业黑马呢&#xff1f;接下来&#xff0c;让我们一一揭秘。 01l品牌运营 行业唯一做统一发货&#xff0c;统一售后的品牌…

Java中 final、finally、finalize 有什么区别?

1、典型回答 final、finally、finalize 是 Java 中三个不同的关键字&#xff0c;它们除了长得像之外&#xff0c;其他的&#xff08;作用和含义&#xff09;完全不同。 它们三个的区别就好像&#xff1a;雷、雷锋、雷峰塔之间的区别。&#xff08;是三个完全不同的东西&#…

深入理解Vue3中利用mitt:实现轻量级事件监听与触发

深入理解Vue3中利用mitt&#xff1a;实现轻量级事件监听与触发 摘要&#xff1a;本文将介绍如何在Vue3中利用mitt库实现轻量级的事件监听与触发。我们将详细介绍mitt库的特性和使用方法&#xff0c;并通过实际示例展示如何在Vue3组件中应用mitt。 一、引言 在前端开发中&…

android studio 老项目突然编译不了,一直下载gradle以及插件

以前这个项目一直可以编译放了几个月&#xff0c;我换了一个windows帐号登录&#xff0c;结果编译不了 之前使用的是gradle-7.2.0&#xff0c;现在由于这几天开会&#xff0c;可能网络不畅通更新不了插件。 原因一&#xff0c;Google仓库连不上 build.gradle注释掉google()和…

web:shrine

题目 点进题目后显示如下 查看源代码&#xff0c;查看可知为ssti注入。还设置了过滤的名单。 先可以测试一下是否存在ssti模板注入 payload \shrine\{{2-2}} 回显成功&#xff0c;存在ssti模板注入 绕过思路&#xff0c;代码里有过滤&#xff0c;会把()替换&#xff0c;这里…

C语言学习基础版(二)

目录 十、结构体和共用体 1、struct结构体的定义和使用 2、结构体数组的使用 3、结构体指针及具体操作 4、union共用体的定义和使用 5、typedef用法 六、enum枚举类型 练习一&#xff1a;星期判断机 练习二&#xff1a;自定义函数之字符串拷贝 练习三&#xff1a;结构…

让手机变相机,微单变全画幅的外设-斯莫格摄影套装开箱

大家好&#xff0c;我是Circaboy&#xff0c;近期给我的手机和相机入了一整套专业的摄影外设套装&#xff0c;然后我发现专业设备加持下的摄影着实是比我之前的要好很多&#xff0c;所以我就写了个文章做个简单的介绍和专业外设加持下的摄影对比。 本次入手的是斯莫格摄影套装…

String类及其常用方法

文章目录 1.String类的特性与使用1.1 String类的特性1.2 String对象的创建方式1.3 String 的使用&#xff08;不同的拼接操作&#xff09; 2.String常用方法2.1 String的常用方法一2.2 String常用方法二2.3 String常用方法三 1.String类的特性与使用 1.1 String类的特性 Stri…

第三百八十五回

文章目录 1.概念介绍2.使用方法3.示例代码 我们在上一章回中介绍了Snackbar Widget相关的内容,本章回中将介绍TimePickerDialog Widget.闲话休提&#xff0c;让我们一起Talk Flutter吧。 1.概念介绍 我们在这里说的TimePickerDialog是一种弹出窗口&#xff0c;只不过窗口的内容…