前方高能《一故事一设计模式》PDF 电子书已经上线,关注公众号即可获取。

个人公众号原文:
创建型模式:建造者模式

五大创建型模式之四:建造者模式。

简介

姓名 :建造者模式

英文名 :Builder Pattern

价值观 :专治丢三落四

个人介绍

Separate the construction of a complex object from its representation so that the same construction process can create different representations.
将一个复杂对象的构建与它的表示分离,使得同样的构建过程可以创建不同的表示。
(来自《设计模式之禅》)

今天给大家介绍的是建造者模式。建造者模式的使用场景是:创建复杂的对象。什么才能算复杂对象?如果一个对象只需要通过 new XXX() 的方式创建,那就算是一个简单对象;如果需要 new XXX(),并且还要设置很多属性,那这种就可以称为复杂对象了,因为它的构建过程比较复杂。采用建造者模式,可以把这个复杂的构建过程抽离开,使它不依赖创建者。下面我们通过故事来讲解。

你要的故事

还记得小时候刚开始学煮汤,不了解怎么煮,第一次是煮了板栗排骨汤,因为板栗比较难熟,所以是跟排骨一起下锅,然后煮了 40 分钟,加了盐就可以出锅啦。第二次煮了冬瓜排骨汤,不懂得冬瓜容易熟,就和排骨一起下锅,煮了也差不多 40 分钟,下了盐和香菜,发现怎么这汤有点浓,冬瓜咋都不见了(全都煮透了),我妈看到这锅汤,才跟我说冬瓜容易熟,得先熬排骨,再放冬瓜进去煮。那时才发现熬汤特么还有这差异。

上面是背景哈,接下来我们来实现这个煲汤过程,冬瓜排骨汤是先加排骨,熬制 30 分钟,加冬瓜,熬制 18 分钟,加盐加香菜;板栗排骨汤是先加排骨和板栗,熬制 40 分钟,再加盐。这汤都需要加肉、加菜、熬制、加配料。我们使用下面代码实现这个煲冬瓜排骨汤和板栗排骨汤的过程。

public class NoBuilderTest {public static void main(String[] args) {// 熬制冬瓜排骨汤DongGuaPaiGuSoup dongGuaPaiGuSoup = new DongGuaPaiGuSoup();// 加排骨dongGuaPaiGuSoup.addMeat();// 熬制 30 分钟dongGuaPaiGuSoup.waitMinute(30);// 加冬瓜dongGuaPaiGuSoup.addVegetables();// 熬制 10 分钟dongGuaPaiGuSoup.waitMinute(10);// 加盐加香菜dongGuaPaiGuSoup.addIngredients();// 熬制板栗排骨汤BanLiPaiGuSoup banLiPaiGuSoup = new BanLiPaiGuSoup();// 加排骨banLiPaiGuSoup.addMeat();// 加板栗banLiPaiGuSoup.addVegetables();// 熬制 40 分钟banLiPaiGuSoup.waitMinute(40);// 加盐banLiPaiGuSoup.addIngredients();}}/*** 煲汤接口*/
interface Soup {/** 加肉 */void addMeat();/** 加菜 */void addVegetables();/** 熬制 */void waitMinute(int minute);/** 加配料 */void addIngredients();}/*** 冬瓜排骨汤*/
class DongGuaPaiGuSoup implements Soup {@Overridepublic void addMeat() {System.out.println("加排骨");}@Overridepublic void addVegetables() {System.out.println("加冬瓜");}@Overridepublic void waitMinute(int minute) {System.out.println("熬制 " + minute + " 分钟");}@Overridepublic void addIngredients() {System.out.println("加盐、加香菜");}
}/*** 板栗排骨汤*/
class BanLiPaiGuSoup implements Soup {@Overridepublic void addMeat() {System.out.println("加排骨");}@Overridepublic void addVegetables() {System.out.println("加板栗");}@Overridepublic void waitMinute(int minute) {System.out.println("熬制 " + minute + " 分钟");}@Overridepublic void addIngredients() {System.out.println("加盐");}
}

上面代码简单实现了煲冬瓜排骨汤和板栗排骨汤。煲汤我们要关注的点是:各操作的顺序,是先加肉先煮再加菜,还是肉和菜一起放进锅煮。上面代码中,这个过程是谁控制的?是煲汤的人,所以顺序由煲汤的人决定,甚至有可能忘记放配料啥的,这样子的汤就味道不够好。那怎么去解决这些问题?

我们通过建造者模式可以解决上面的 2 个问题:煲汤顺序问题和忘记加配料这种丢三落四行为。我们将这个煲汤顺序从煲汤者分离开来,让煲汤者只需要决定煲什么汤就好,让建造者来保证煲汤顺序问题和防止漏加配料。

我们用一个 SoupBuilder 来规范化煲汤过程,方法 buildSoup 给实现者提供一个设置煲汤顺序的地方。因为冬瓜排骨汤和板栗排骨汤熬制的过程不一样,所以分别用 DongGuaPaiGuSoupBuilder 和 BanLiPaiGuSoupBuilder 来具体实现冬瓜排骨汤和板栗排骨汤的熬制过程,也就是消除熬制过程和煲汤者的依赖关系。 Director 则相当于一个菜单,提供为熬汤者来选择熬什么汤。具体代码如下所示。

public class BuilderTest {public static void main(String[] args) {Director director = new Director();// 熬制冬瓜排骨汤director.buildDongGuaPaiGuSoup();// 熬制板栗排骨汤director.buildBanLiPaiGuSoup();}}/*** 煲汤建造接口*/
interface SoupBuilder {void buildSoup();Soup getSoup();
}/*** 冬瓜排骨汤建造者*/
class DongGuaPaiGuSoupBuilder implements SoupBuilder {private DongGuaPaiGuSoup dongGuaPaiGuSoup = new DongGuaPaiGuSoup();@Overridepublic void buildSoup() {// 加排骨dongGuaPaiGuSoup.addMeat();// 熬制 30 分钟dongGuaPaiGuSoup.waitMinute(30);// 加冬瓜dongGuaPaiGuSoup.addVegetables();// 熬制 10 分钟dongGuaPaiGuSoup.waitMinute(10);// 加盐加香菜dongGuaPaiGuSoup.addIngredients();}@Overridepublic Soup getSoup() {return dongGuaPaiGuSoup;}
}/*** 板栗排骨汤建造者*/
class BanLiPaiGuSoupBuilder implements SoupBuilder {BanLiPaiGuSoup banLiPaiGuSoup = new BanLiPaiGuSoup();@Overridepublic void buildSoup() {// 加排骨banLiPaiGuSoup.addMeat();// 加板栗banLiPaiGuSoup.addVegetables();// 熬制 40 分钟banLiPaiGuSoup.waitMinute(40);// 加盐banLiPaiGuSoup.addIngredients();}@Overridepublic Soup getSoup() {return banLiPaiGuSoup;}
}/*** 生产方*/
class Director {private DongGuaPaiGuSoupBuilder dongGuaPaiGuSoupBuilder = new DongGuaPaiGuSoupBuilder();private BanLiPaiGuSoupBuilder banLiPaiGuSoupBuilder = new BanLiPaiGuSoupBuilder();/*** 熬制冬瓜排骨汤*/public DongGuaPaiGuSoup buildDongGuaPaiGuSoup() {dongGuaPaiGuSoupBuilder.buildSoup();return (DongGuaPaiGuSoup) dongGuaPaiGuSoupBuilder.getSoup();}/*** 熬制板栗排骨汤*/public BanLiPaiGuSoup buildBanLiPaiGuSoup() {banLiPaiGuSoupBuilder.buildSoup();return (BanLiPaiGuSoup) banLiPaiGuSoupBuilder.getSoup();}}

通过用建造者实现,是不是保证了熬制汤的顺序并且一定会加够料?感受一下其中的奥秘吧。

代码:
Builder Pattern

总结

通过建造者模式,可以把本来强依赖的东西解绑,不仅仅解决依赖问题,还提高了封装性,让使用者不用明白内部的细节,用上面的例子说就熬汤不用关心怎么熬制的过程,就像我们想喝冬瓜排骨汤,告诉妈妈,妈妈熬制,我们并不知道是怎么熬制的。

参考资料:《大话设计模式》、《Java设计模式》、《设计模式之禅》、《研磨设计模式》、《Head First 设计模式》

推荐阅读:
创建型模式:单例模式
创建型模式:工厂方法
创建型模式:抽象工厂
公众号之设计模式系列文章

希望文章对您有所帮助,设计模式系列会持续更新,感兴趣的同学可以关注公众号:LieBrother,第一时间获取文章推送阅读,也可以一起交流,交个朋友。

创建型模式:建造者模式相关推荐

  1. Java设计模式之创建型:建造者模式

    一.什么是建造者模式: 建造者模式将复杂产品的创建步骤分解在在不同的方法中,使得创建过程更加清晰,从而更精确控制复杂对象的产生过程:通过隔离复杂对象的构建与使用,也就是将产品的创建与产品本身分离开来, ...

  2. 设计模式(创建型)之建造者模式(Builder Pattern)

    PS一句:最终还是选择CSDN来整理发表这几年的知识点,该文章平行迁移到CSDN.因为CSDN也支持MarkDown语法了,牛逼啊! [工匠若水 http://blog.csdn.net/yanbob ...

  3. Java创建型设计模式——建造者模式

    文章目录 1.0概念理解 2.0编码理解 2.1编码说明 2.2编码实现 五种创建型设计模式:工厂方法模式.抽象工厂模式.建造者模式.原型模式.单例模式 1.0概念理解 ​ ​ 一句话理解:建造者模式 ...

  4. java设计模式——创建型之建造者模式

    自大学课程初识设计模式以来,就越发觉得有必要系统学习一下设计模式. 刚好在实习前准备期间课比较少,抽出一点时间整理一下记一些笔记,复制粘贴比较多. 笔记比较适合学习过设计模式的同学. Builder ...

  5. 每天学习一个设计模式(九):创建型之建造者模式

    目录 一.基本概念 二.通俗解释 三.建造者模式详解 1.造车的例子 2.建造者模式的结构 3.建造者模式的优点 4.使用场景 5.注意事项 四.建造者模式的扩展和最佳实践 建造者模式的扩展 最佳实践 ...

  6. 创建型设计模式——建造者模式

    1.提出问题 假如说,我们需要建房子:这一过程为打桩.砌墙.封顶.房子有各种各样的,比如普通房,高楼,别墅,各种房子的过程虽然一样,但是要求不要相同的.3)请编写程序,完成需求. 传统的想法应该就是下 ...

  7. 【创建型】建造者模式(Builder Pattern)

    主要作用: 可以使多个简单的对象,一步一步构建成一个复杂的对象 应用实例: 1.去肯德基,汉堡.可乐.薯条.炸鸡翅等是不变的,而其组合是经常变化的,生成出所谓的"套餐". 2.JA ...

  8. 创建型设计模模式---建造者模式

    设计模式 序号 内容 链接地址 1 设计模式七大原则 https://blog.csdn.net/qq_39668819/article/details/115390615 2 创建型设计模式–工厂模 ...

  9. Java设计模式之创建型:原型模式

    一.什么是原型模式: 原型模式主要用于对象的创建,使用原型实例指定创建对象的种类,并通过拷贝这些原型创建新的对象.UML类图如下: 原型模式的核心是就是原型类 Prototype,Prototype ...

  10. 创建型设计模模式---原型模式

    设计模式 序号 内容 链接地址 1 设计模式七大原则 https://blog.csdn.net/qq_39668819/article/details/115390615 2 创建型设计模式–工厂模 ...

最新文章

  1. python处理流程-Python文件处理流程
  2. ITK:将像素缓冲区导入到图像中
  3. spring配置详解-属性注入(构造函数)
  4. Java知识系统回顾整理01基础04操作符05赋值操作符
  5. 深度学习之数据增强方案和TensorFlow操作
  6. 论文浅尝 - AAAI2020 | 利用自然语言推断生成人称一致的对话
  7. 自动发卡企业商户运营版带WAP手机端+多种主题
  8. apache虚拟主机、日志轮询、日志统计、去版本优化
  9. 阿里平头哥“生娃”!最强 RISC-V 处理器玄铁 910 诞生!
  10. SSH框架微服务改进实战
  11. 研究生从事学术研究的赫曼法则(The Laws of Herman)。
  12. 用Now SMS/MMS 发送中国移动彩信
  13. 2023最新SSM计算机毕业设计选题大全(附源码+LW)之java社团管理系统0gl2e
  14. 查看在线人物 修改金币 元宝 等人物属性
  15. XTransfer技术专家康康:从普通程序员到架构师的进化之路
  16. LeetCode——11. 盛最多水的容器
  17. 传统分布式架构部署(apache+tomcat集群)
  18. python-----列表生成式和列表生成器表达
  19. 7.26第二课课堂笔记
  20. 文本处理三剑客之sed命令详解

热门文章

  1. GitLab提交代码SSL证书过期解决
  2. sudo: mvn: command not found
  3. oracle 解决序列号自增报 java.sql.SQLException: ORA-00001: 违反唯一约束条件 问题
  4. 第1题 给定一个整数数组 nums 和一个目标值 target,请你在该数组中找出和为目标值的那 两个 整数,并返回他们的数组下标
  5. python socket ICMP 进行通信
  6. 电网质量-谐波的基本概念
  7. 我爱你崔紫娟——康益明
  8. 解决pip install报错:setup command: use_2to3 is invalid
  9. 表格标签 ,待支付、未支付转换,可直接复制使用
  10. QTS公司将在芝加哥开通运营数据中心