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

好菜每回味不同——建造者模式

文章目录

  • 好菜每回味不同——建造者模式
    • 炒面没放盐
    • 建造小人一
    • 建造小人二
    • 建造者模式
    • 建造者模式解析

好菜每回味不同——建造者模式

炒面没放盐

时间:4月9日22点  地点:小菜、大鸟住所的客厅  人物:小菜、大鸟

"小菜,讲了半天,肚子饿得厉害,走,去吃夜宵去。"大鸟摸着肚子说道。

“你请客?!”

“我教了你这么多,你也不打算报答一下,还要我请客?搞没搞错。”

"啊,说得也是,这样吧,我请客,你埋单,嘻嘻!"小菜傻笑道,“我身上没带钱。”

"你这个菜穷酸,行了,我来埋单吧。"大鸟等不及了,拿起外套就往外走。

“等等我,我把电脑关一下……”

时间:4月9日22:30  地点:小区外大排档  人物:小菜、大鸟

小区门口大排档前。

"老板,来两份炒饭。"大鸟对大排档的老板说。

"大鸟太小气,就请吃炒饭呀,"小菜埋怨道,“我要吃炒面。”

"再说废话,你请客了哦!"大鸟瞪了小菜一眼,接着对老板说,“那就一份炒饭一份炒面吧。”

十分钟后。

"这炒饭炒得什么玩意儿,味道不够,鸡蛋那么少,估计只放了半个。"大鸟吃得很不爽,抱怨道。

"炒面好好吃哦,真香。"小菜故意嘟囔着,把面吸得嗉嗉直响。

"让我尝尝,"大鸟强拉过小菜的盘子,吃了一口,“好像味道是不错,你小子运气好。老板,再给我来盘炒面!”

在这里插入图片描述

五分钟后。

"炒面来了,客官请慢用。"老板仿佛古时的小二一般来了一句。

"啊,老板,这炒面没放盐……"大鸟叫道。

……

时间:4月9日23:15  地点:回小区的路上  人物:小菜、大鸟

在回去的路上,大鸟感慨道:“小菜,你知道为什么麦当劳、肯德基这些不过百年的洋快餐能在有千年饮食文化的中国发展得这么好吗?”

“他们比较规范吧,味道好吃,而且还不出错,不会出现像你今天这样,蛋炒饭不好吃,炒面干脆不放盐的情况。”

在这里插入图片描述

“你说得没错,麦当劳、肯德基的汉堡,不管在哪家店里吃,什么时间去吃,至少在中国,味道基本都是一样的。而我们国家,比如那道’鱼香肉丝’,几乎是所有大小中餐饭店都有的一道菜,但却可以吃出上万种口味来,这是为什么?”

“厨师不一样呀,每个人做法不同的。”

“是的,因为厨师不同,他们学习厨艺方法不同,有人是科班出身,有人是师傅带徒弟,有人是照书下料,还有人是自我原创,哈,这样你说同样的菜名’鱼香肉丝’,味道会一样吗?”

“还不只是这些,同一个厨师,不同时间烧出来同样的菜也不一样的,盐多盐少,炒的火候时间的长短,都是不一样的。”

“说得好,那你仔细想想,麦当劳、肯德基比我们很多中式快餐成功的原因是什么?”

“就感觉他们比较规范,具体原因也说不上来。”

“为什么你的炒面好吃,而我再要的炒面却没有放盐?这好吃不好吃由谁决定?”"当然是烧菜的人,他感觉好,就是一盘好面,要是心情不好,或者粗心大意,就是一盘垃圾。"小菜肯定地说。

“哈,说得没错,今天我就吃了两盘垃圾,其实这里面最关键的就在于我们是吃得爽还是吃得难受都要依赖于厨师。你再想想我们设计模式的原则?”

“啊,你的意思是依赖倒转原则?抽象不应该依赖细节,细节应该依赖于抽象,由于我们要吃的菜都依赖于厨师这样的细节,所以我们就很被动。”

“好,那再想想,老麦老肯他们的产品,味道是由什么决定的?”

“我知道,那是由他们的工作流程决定的,由于他们制定了非常规范的工作流程,原料放多少,加热几分钟,都有严格规定,估计放多少盐都是用克来计量的。而这个工作流程是在所有的门店都必须要遵照执行的,所以我们吃到的东西不管在哪在什么时候味道都一样。这里我们要吃的食物都依赖工作流程。不过工作流程好像还是细节呀。”

“对,工作流程也是细节,我们去快餐店消费,我们用不用关心他们的工作流程?当然是不用,我们更关心的是是否好吃。你想如果老肯发现鸡翅烤得有些焦,他们会调整具体的工作流程中的烧烤时间,如果新加一种汉堡,做法都相同,只是配料不相同,工作流程是不变的,只是加了一种具体产品而已,这里工作流程怎么样?”

“对,这里工作流程可以是一种抽象的流程,具体放什么配料、烤多长时间等细节依赖于这个抽象。”

建造小人一

“给你出个题目,看看你能不能真正体会到流程的抽象。我的要求是你用程序画一个小人,这在游戏程序里非常常见,现在简单一点,要求是小人要有头、身体、两手、两脚就可以了。”

“废话,人还会有多手多脚呀,那不成了蜈蚣或螃蟹。这程序不难呀,我回去就写给你看。”

时间:4月9日23:30  地点:小菜大鸟住所的客厅  人物:小菜、大鸟

“大鸟,程序写出来了,我建立一个窗口JFrame,在上面画了一个小人,简单了点,但功能实现了。”

在这里插入图片描述

“写得很快,那么我现在要你再画一个身体比较胖的小人呢。”

“那不难呀,我马上做好。”

在这里插入图片描述

“哈,这就和我们刚才去吃炒面一样,老板忘记了放盐,让本是美味的夜宵变得无趣。如果是让你开发一个游戏程序,里面的人物却少了一条腿,那怎么能行?”

“是呀,画人的时候,头身手脚是必不可少的,开发时也是不能少的。”

“你现在的代码全写在Test.java里,我要是需要在别的地方用这些画小人的程序怎么办?”

建造小人二

“嘿,你的意思是分离,这不难办,我建两个类,一个是瘦人的类,一个是胖人的类,不管谁都可以调用它了。”

在这里插入图片描述

“胖人的类也是相似的。然后我在客户端里就只需这样写就可以了。”

在这里插入图片描述

"你这样写的确达到了可以复用这两个画小人程序的目的。"大鸟说,“但炒面忘记放盐的问题依然没有解决。比如我现在需要你加一个高个的小人,你会不会因为编程不注意,又让他缺胳膊少腿呢?”

“是呀,最好的办法是规定,凡是建造小人,都必须要有头和身体,以及两手两脚。”

建造者模式

“你仔细分析会发现,这里建造小人的’过程’是稳定的,都需要头身手脚,而具体建造的’细节’是不同的,有胖有瘦有高有矮。但对于用户来讲,我才不管这些,我只想告诉你,我需要一个胖小人来游戏,于是你就建造一个给我就行了。如果你需要将一个复杂对象的构建与它的表示分离,使得同样的构建过程可以创建不同的表示的意图时,我们需要应用于一个设计模式,'建造者模式(Builder)',又叫生成器模式。建造者模式可以将一个产品的内部表象与产品的生成过程分割开来,从而可以使一个建造过程生成具有不同的内部表象的产品对象。如果我们用了建造者模式,那么用户就只需指定需要建造的类型就可以得到它们,而具体建造的过程和细节就不需要知道了。

建造者模式(Builder),将一个复杂对象的构建与它的表示分离,使得同样的构建过程可以创建不同的表示。[DP]

“那怎么用建造者模式呢?”

“一步一步来,首先我们要画小人,都需要画什么?”“头、身体、左手、右手、左脚、右脚。”

“对的,所以我们先定义一个抽象的建造人的类,来把这个过程给稳定住,不让任何人遗忘当中的任何一步。”

在这里插入图片描述

“然后,我们需要建造一个瘦的小人,则让这个瘦子类去继承这个抽象类,那就必须去重写这些抽象方法了。否则编译器也不让你通过。”

在这里插入图片描述

“当然,胖人或高个子其实都是用类似的代码去实现这个类就可以了。”

"这样,我在客户端要调用时,还是需要知道头身手脚这些方法呀?没有解决问题。"小菜不解地问。“别急,我们还缺建造者模式中一个很重要的类,指挥者(Director),用它来控制建造过程,也用它来隔离用户与建造过程的关联。”

在这里插入图片描述

“你看到没有,PersonDirector类的目的就是根据用户的选择来一步一步建造小人,而建造的过程在指挥者这里完成了,用户就不需要知道了,而且,由于这个过程每一步都是一定要做的,那就不会让少画了一只手,少画一条腿的问题出现了。”

“代码结构图如下。”

在这里插入图片描述

“哈,我明白了,那客户端的代码我来写吧。应该也不难实现了。”

在这里插入图片描述

“试想一下,我如果需要增加一个高个子和矮个子的小人,我们应该怎么做?”

" 加 两 个 类 , 一 个 高 个 子 类 和 一 个 矮 个 子 类 , 让 它 们 都 去 继 承PersonBuilder,然后客户端调用就可以了。但我有个问题,如果我需要细化一些,比如人的五官,手的上臂、前臂和手掌,大腿小腿这些,如何办呢?"

“问得好,这就需要权衡,如果这些细节是每个具体的小人都需要构建的,那就应该要加进去,反之就没必要。其实建造者模式是逐步建造产品的,所以建造者的Builder类里的那些建造方法必须要足够普遍,以便为各种类型的具体建造者构造。”

建造者模式解析

“来,我们看看建造者模式的结构。”

建造者模式(Builder)结构图:

在这里插入图片描述

“现在你看这张图就不会感觉陌生了。来总结一下,Builder是什么?”

“是一个建造小人各个部分的抽象类。”

**“概括地说,是为创建一个Product对象的各个部件指定的抽象接口。**ConcreteBuilder是什么呢?”

“具体的小人建造者,具体实现如何画出小人的头身手脚各个部分。”

"对的,它是具体建造者,实现Builder接口,构造和装配各个部件

Product当然就是那些具体的小人,产品角色了,Director是什么?"

“指挥者,用来根据用户的需求构建小人对象。”

“嗯,它是构建一个使用Builder接口的对象。”

“那都是什么时候需要使用建造者模式呢?”

“它主要用于创建一些复杂的对象,这些对象内部子对象的建造顺序通常是稳定的,但每个子对象本身的构建通常面临着复杂的变化。”

“哦,是不是建造者模式的好处就是使得建造代码与表示代码分离,由于建造者隐藏了该产品是如何组装的,所以若需要改变一个产品的内部表示,只需要再定义一个具体的建造者就可以了。”

“来来来,我们来试着把建造者模式的基本代码推演一下,以便有一个更宏观的认识。”

Product类——产品类,由多个部件组成。

在这里插入图片描述

Builder类——抽象建造者类,确定产品由两个部件PartA和PartB组成,并声明一个得到产品建造后结果的方法GetResult。

在这里插入图片描述

ConcreteBuilder1类——具体建造者类。

在这里插入图片描述

ConcreteBuilder2类——具体建造者类。

在这里插入图片描述

“所以说,建造者模式是在当创建复杂对象的算法应该独立于该对象的组成部分以及它们的装配方式时适用的模式。”

“如果今天大排档做炒面的老板知道建造者模式,他就明白,盐是一定要放的,不然,编译就通不过。”

“什么呀,不然,钱就赚不到了,而且还大大丧失我们对他厨艺的信任。看来,各行各业都应该要懂模式呀。”

如果对你有帮助,就一键三连呗(关注+点赞+收藏),我会持续更新更多干货~~


http://www.kler.cn/news/311790.html

相关文章:

  • GEE教程:对降水数据进行重投影(将10000m分辨率提高到30m)
  • ESP32配网接入Wifi
  • Spring Boot从0到1 -day02
  • 【踩坑】装了显卡,如何让显示器从主板和显卡HDMI都输出
  • QTAndroid编译环境配置
  • Linux基础命令——文件系统的日常管理
  • TaskRes: Task Residual for Tuning Vision-Language Models
  • vue项目中——如何用echarts实现动态水球图
  • 828华为云征文 | 华为云X实例监控与告警管理详解
  • 【Linux入门】基本指令(一)
  • 服务器上PFC配置丢失问题排查与解决方案
  • Python | Leetcode Python题解之第412题Fizz Buzz
  • 简评2024.9.16北京大运河音乐节
  • Prompt最佳实践|指定输出的长度
  • 深度学习自编码器 - 收缩自编码器(CAE)篇
  • 74、Python之函数式编程:深入理解惰性求值与生成器
  • MySql 初次见面
  • Java 基础知识九(网络编程)
  • 二叉树(下)
  • Conda Config修改
  • 深度学习-18-深入理解BERT实战使用预训练的DistilBERT模型
  • 【Vue嵌套数据中,实现动态表头和内容】
  • 不会JS逆向也能高效结合Scrapy与Selenium实现爬虫抓取
  • 前端框架对比和选择?
  • [学习笔记]树链剖分(简易版) 及其LCA
  • Redis实践之缓存:设置缓存过期策略
  • 计算机网络33——文件系统
  • sqli-labs靶场自动化利用工具——第13关
  • RabbitMQ 和 Kafka 的详细对比表格
  • 消息队列:如何确保消息不会丢失?