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.hqwc.cn/news/537948.html

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

相关文章

Spring揭秘:ClassPathScanningProvider接口应用场景及实现原理!

技术应用场景 ClassPathScanningCandidateComponentProvider是Spring框架中一个非常核心的类,它主要用于在类路径下扫描并发现带有特定注解的组件,支持诸如ComponentScan、Component、Service、Repository和Controller等注解的自动扫描和注册。 ClassP…

2024硬核对比内衣洗衣机:dailyneaty、希亦、觉飞大pk

内衣和贴身衣物的面料通常比较柔软和脆弱,如果和其他衣物混洗,可能会因摩擦和拉伸等原因导致面料损坏、变形或者开线,而内衣洗衣机可以采用低速旋转、柔和的清洗方式,避免这种情况的发生,因此,内衣洗衣机可…

C#,数值计算,希尔伯特矩阵(Hilbert Matrix)的算法与源代码

Hilbert, David (1862-1943) 1 希尔伯特(Hilbert) 德国数学家,在《几何学基础》中提出了第一套严格的几何公理(1899年)。他还证明了自己的系统是自洽的。他发明了一条简单的空间填充曲线,即埃里克魏斯汀的数学世界,即希尔伯特曲线,埃里克魏斯汀的数学世界,并证明了不…

Linux 建立链接(ln)

目录 1、ln命令 创建软链接: 创建硬链接: 2、输出重定向(>/>>) 3、管道(|) 1、ln命令 (英文全拼:link files)为某一个文件在另外一个位置建立一个同步的…

实践致知第9享:Word中标题编号无法正常编辑

一、背景需求 在编辑文档时,多级目录结构却无法正常编辑。 二、解决方案 1右键选择“项目符号和编号”查看是否上下文中的编号格式都保持一致,如下图所示。 2当调整到同一种样式之后,用格式刷刷一下需要编辑的标题,先刷成同级别…

自动化运维工具Ansible

目录 一.Ansible基本内容 1.定义 2.特点与优势 优势: (1)轻便性:无需在被控制服务器上安装客户端,Ansible基于ssh协议 (2)幂等性:大部分模块有幂等性,即如果输入sys…

【LeetCode热题100】24. 两两交换链表中的节点(链表)

一.题目要求 给你一个链表,两两交换其中相邻的节点,并返回交换后链表的头节点。你必须在不修改节点内部的值的情况下完成本题(即,只能进行节点交换)。 二.题目难度 中等 三.输入样例 示例 1: 输入&am…

武汉星起航:创新驱动,共赢未来,引领跨境电商新潮流

在跨境电商这个充满挑战与机遇的领域,武汉星起航凭借其创新思维和共赢理念,正引领着行业发展的新潮流。 武汉星起航深知创新是企业在激烈竞争中立于不败之地的关键。公司始终关注市场动态,紧跟行业趋势,不断探索新的商业模式和运…

【Redis】Redis常用命令一

1.keys:返回所有满足条件的key,比如: KEYS pattern时间复杂度:O(N),返回值:匹配pattern的所有key。 • h?llo 匹配 hello , hallo 和 hxllo • h*llo 匹配 hllo 和 heeeello • h[ae]llo 匹配 hello 和 …

回收站清空了怎么恢复回来?这四种回收站数据恢复方法要知道

在使用电脑的过程中,我们难免会遇到误删文件的情况。一旦不小心清空了回收站,那些被删除的文件似乎就永远消失了。但其实,在一定条件下,我们还是有机会恢复这些文件的。本文将介绍四种不同的方法,帮助你在回收站清空后…

刷题日记——礼炮车(厦门大学机试)

例题——礼炮车 方法一:按照开炮时间对时间间隔取余 第一炮设置都是第0秒打响,那么: 间隔为5的炮车打响第n炮,应该在(n-1)*5秒间隔为6的炮车打响第n炮,应该在(n-1)*6秒…

STM32 晶振(用示波器测RCC频率是否一致)

如果测出的频率不准确,可以修改一下看看是否有改善: