烤羊肉串引来的思考——命令模式

news2024/11/15 19:41:20

文章目录

  • 烤羊肉串引来的思考——命令模式
    • 吃烤羊肉串!
    • 烧烤摊vs.烧烤店
    • 紧耦合设计
    • 命令模式
    • 松耦合设计
    • 进一步改进命令模式
    • 命令模式的作用

烤羊肉串引来的思考——命令模式

吃烤羊肉串!

时间:6月23日17点  地点:小区门口  人物:小菜、大鸟

“小菜,肚子饿了,走,我请你吃羊肉串。”

在这里插入图片描述

“好呀,小区门口那有个新疆人烤得就很不错。”

小菜和大鸟来到了小区门口。

"啊,这么多人,都围了十几个。"小菜感叹道。

“现在读大学,进公司,做白领,其实未必有人家烤羊肉串的挣得多。”

“这是两回事,人家也很辛苦呀。”

此时,老板烤的第一批羊肉好了。

“老板,我这有两串。”

“老板,我的是三串不辣的。”

“老板,你怎么给她了,我先付的钱!”

“老板,这串不太熟呀,再烤烤。”

“老板,我老早就等在这里,钱早给你了,你都不给我,我不要了。退钱!”

旁边等着拿肉串的人七嘴八舌地叫开了。场面有些混乱,由于人实在太多,烤羊肉串的老板已经分不清谁是谁,造成分发错误,收钱错误,烤肉质量不过关等。

"小菜,我看我们还是换一家吧,这里实在太混乱了,过去不远有一家烤

肉店是有店面的。"

“嗯,他这样子生意是做不好。咱们去那一家吧。”

时间:6月2日18点  地点:烤肉店  人物:小菜、大鸟、服务员

小菜和大鸟走到了那家烤肉店。

"服务员,我们要十串羊肉串、两串鸡翅、两瓶啤酒。"大鸟根本没有看菜单。

"鸡翅没有了,您点别的烧烤吧。"服务员答道。

"那就来四串牛板筋,烤肉要辣的。"大鸟轻车熟路。

"大鸟常来这里吃吗?很熟悉嘛!"小菜问道。

“太熟悉了,这年头,单身在外混,哪有不熟悉家门口附近的吃饭的地。不然每天晚上的肚皮问题怎么解决?”

"你说,在外面打游击烤羊肉串和这种开门店做烤肉,哪个更赚钱?"小菜问道。

“哈,这很难讲,毕竟各有各的好,在外面打游击,好处是不用租房,不用上税,最多就是交点’保护费’,但下雨天不行、大白天不行、太晚也不行,一般都是傍晚做几个钟头,顾客也不固定,像刚才那个,由于人多造成混乱,于是就放跑了我们这两条大鱼,其实他的生意是不稳定的。”

“大白天不行?太晚不行?”

“大白天,城管没下班呢,怎能容忍他如此安逸。超过晚上11点,夜深人静,谁还愿意站在路边吃烤肉。但开门店就不一样了,不管什么时间都可以做生意,由于环境相对好,所以固定客户就多,看似好像房租交出去了,但其实由于顾客多,而且是正经做生意,所以最终可以赚到大钱。”

“大鸟研究得很透嘛。”

“其实这门店好过马路游击队,还可以对应一个很重要的设计模式呢!”

“哦,此话怎讲?”

烧烤摊vs.烧烤店

在这里插入图片描述

“你再回忆刚才在我们小区门口烤肉摊看到的情景。”

“因为要吃烤肉的人太多,都希望能最快吃到肉串,烤肉老板一个人,所以有些混乱。”

“还不止这些,老板一个人,来的人一多,他就未必记得住谁交没交过钱,要几串,需不需要放辣等。”

“是呀,大家都站在那里,没什么事,于是都盯着烤肉去了,哪一串多、哪一串少、哪一串烤得好、哪一串烤得焦看得清清楚楚,于是’挑剔’也就接踵而至。”

“这其实就是我们在编程中常说的什么?”

“我想想,你是想说’紧耦合’?”

“哈,不错,不枉我的精心栽培。”

“由于客户和烤羊肉串老板的’紧耦合’,所以容易出错,也容易产生挑剔。”

“说得对,这其实就是**'行为请求者’与’行为实现者’的紧耦合**。我们需要记录哪个人要几串羊肉串,有没有特殊要求(放辣不放辣),付没付过钱,谁先谁后,这其实都相当于对请求做什么?”

“对请求做记录,啊,应该是做日志。”

“很好,那么如果有人需要退回请求,或者要求烤肉重烤,这其实就是?”

“就相当于撤销和重做吧。”

“OK,所以对请求排队或记录请求日志,以及支持可撤销的操作等行为时,'行为请求者’与’行为实现者’的紧耦合是不太适合的。你说怎么办?”

“开家门店。”

“哈,这是最终结果,不是这个意思,我们是烤肉请求者,烤肉的师傅是烤肉的实现者,对于开门店来说,我们用得着去看着烤肉的实现过程吗?现实是怎么做的呢?”

“哦,我明白你的意思了,我们不用去认识烤肉者是谁,连他的面都不用见到,我们只需要给接待我们的服务员说我们要什么就可以了。他可以记录我们的请求,然后再由他去通知烤肉师傅做。”

“而且,由于我们所做的请求,其实也就是我们点肉的订单,上面有很详细的我们的要求,所有的客户都有这一份订单,烤肉师傅可以按先后顺序操作,不会混乱,也不会遗忘了。”

“收钱的时候,也不会多收或少收。”

"优点还不止这里,比如说,"大鸟突然大声叫道,“服务员,我们那十串羊肉串太多了,改成六串就可以了。”

"好的!"服务员答道。

大鸟接着说:“你注意看他接着做了什么?”

“他好像在一个小本子上划了一下,然后去通知烤肉师傅了。”

“这其实是在做撤销行为的操作。由于有了记录,所以最终算账是不会错的。”

“对对对,这种利用一个服务员来解耦客户和烤肉师傅的处理好处真的很多。”

“好了,这里有纸和笔,你把刚才的想法写成代码吧?”

“啊,在这?”

“这才叫让编程融入生活。来吧,不写出来,你是不能完全理解的。”

“好吧,我试试看。”

紧耦合设计

边吃着烤肉串,边写着代码,小菜完成了第一版。

在这里插入图片描述

“很好,这就是路边烤肉的对应,如果用户多了,请求多了,就容易乱了。那你再尝试用门店的方式来实现它。”

“我知道一定需要增加服务员类,但怎么做有些不明白。”

“嗯,这里的确是难点,要知道,不管是烤羊肉串,还是烤鸡翅,还是其他烧烤,这些都是’烤肉串者类’的行为,也就是他的方法,具体怎么做都是由方法内部来实现,我们不用去管它。但是对于’服务员’类来说,他其实就是根据用户的需要,发个命令,说:‘有人要十个羊肉串,有人要两个鸡翅’,这些都是命令……”

"我明白了,你的意思是,把’烤肉串者’类当中的方法,分别写成多个命

令类,那么它们就可以被’服务员’来请求了?"

"是的,说得没错,这些命令其实差不多都是同一个样式,于是你就可以

泛化出一个抽象类,让’服务员’只管对抽象的’命令’发号施令就可以了。具

体是什么命令,即烤什么,由客户来决定吧。"

“具体怎么做到呢?”

“我来给你介绍一下大名鼎鼎的命令模式吧。”

命令模式

命令模式(Command),将一个请求封装为一个对象,从而使你可用不同的请求对客户进行参数化;对请求排队或记录请求日志,以及支持可撤销的操作[DP]

在这里插入图片描述

Command类,用来声明执行操作的接口。

在这里插入图片描述

ConcreteCommand类,将一个接收者对象绑定于一个动作,调用接收者相应的操作,以实现executeCommand。

在这里插入图片描述

客户端代码,创建一个具体命令对象并设定它的接收者。

在这里插入图片描述

“你试试看,用上面的方法写一下饭店点菜的代码。”

松耦合设计

小菜经过思考,把第二个版本的代码写了出来。

在这里插入图片描述

烤肉串者类与之前相同。

在这里插入图片描述

抽象命令类:

在这里插入图片描述

客户端代码:

在这里插入图片描述

“大鸟,我这样写如何?”

“很好很好,基本都把代码实现了。但没有体现出命令模式的作用。比如下面几个问题:第一,真实的情况其实并不是用户点一个菜,服务员就通知厨房去做一个,那样不科学,应该是点完烧烤后,服务员一次通知制作;第二,如果此时鸡翅没了,不应该是客户来判断是否还有,客户哪知道有没有呀,应该是服务员或烤肉串者来否决这个请求;第三,客户到底点了哪些烧烤或饮料,这是需要记录日志的,以备收费,也包括后期的统计;第四,客户完全有可能因为点的肉串太多而考虑取消一些还没有制作的肉串。这些问题都需要得到解决。”

“这,这怎么办到呀?”

" 重 构 一 下 服 务 员 Waiter 类 , 尝 试 改 一 下 。 将 private Command command;改成一个ArrayList,就能解决了。"

“嗯。我试试看……”

进一步改进命令模式

小菜开始了第三版的代码编写。

服务员类:

在这里插入图片描述

客户端代码:

在这里插入图片描述

结果显示:

在这里插入图片描述

"哈,这就比较完整了。"大鸟满意地点点头。

命令模式的作用

“来来来,小菜你来总结一下命令模式的优点。”

“我觉得第一,它能较容易地设计一个命令队列;第二,在需要的情况下,可以较容易地将命令记入日志;第三,允许接收请求的一方决定是否要否决请求。”

"还有就是第四,可以容易地实现对请求的撤销和重做;第五,由于加进新的具体命令类不影响其他的类,因此增加新的具体命令类很容易。其实还有最关键的优点就是命令模式把请求一个操作的对象与知道怎么执行一个操作的对象分割开。[DP]"大鸟接着总结说。

“但是否是碰到类似情况就一定要实现命令模式呢?”

“这就不一定了,比如命令模式支持撤销/恢复操作功能,但你还不清楚是否需要这个功能时,你要不要实现命令模式?”

“要,万一以后需要就不好办了。”

“其实应该是不要实现。敏捷开发原则告诉我们,不要为代码添加基于猜测的、实际不需要的功能。如果不清楚一个系统是否需要命令模式,一般就不要着急去实现它,事实上,在需要的时候通过重构实现这个模式并不困难,只有在真正需要如撤销/恢复操作等功能时,把原来的代码重构为命令模式才有意义。[R2P]”

"明白。这一顿我请客了。"小菜很开心,大声叫了一句,“服务员,买单。”

"先生,你们一共吃了28元。"服务员递过来一个收费单。

小菜正准备付钱。

"慢!"大鸟按住小菜的手,“不对呀,我们没有吃10串羊肉串,后来改成6串了。应该是24元。”

服务员去查了查账本,回来很抱歉地说,“真是对不起,我们算错了,应该是24元。”

“小菜,你看到了吧,如果不是服务员做了记录,也就是记日志,单就烤肉串的人,哪记得住烤了多少串,后果就是大家都说不清楚了。”

“还是大鸟精明呀。”

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

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

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

相关文章

企业EMS -能源管理系统-能源在线监测平台

一、介绍 基于SpringCloud的能管管理系统-能源管理平台源码-能源在线监测平台-双碳平台源码-SpringCloud全家桶-能管管理系统源码 二、软件架构 二、功能介绍 三、数字大屏展示 四、数据采集原理 五、软件截图

在不受支持的 Mac 上安装 macOS Sequoia (OpenCore Legacy Patcher v2.0.1)

在不受支持的 Mac 上安装 macOS Sequoia (OpenCore Legacy Patcher v2.0.1) Install macOS on unsupported Macs 请访问原文链接:https://sysin.org/blog/install-macos-on-unsupported-mac/,查看最新版。原创作品,转载请保留出处。 作者主…

吉客云与金蝶云星空对接集成分页查询货品信息连通[标准]

吉客云与金蝶云星空对接集成分页查询货品信息连通[标准][付款单新增]-v1(付款单) 对接系统:吉客云 “吉客云”是一站式企业数字化解决方案系统,可实现业务、财务、办公、人事等一体化管理。相对于传统多套软件系统的集成方案,“吉客云”具有业…

剖析:基于 RDMA 的多机数据分发和接收场景

在基于 RDMA 的多机数据分发和接收场景中,数据的传输主要依赖于以下几个步骤和角色: 机器 A(发送方):通过 RDMA 将数据直接写入远程机器的内存中。机器 B(接收方):接收数据&#xf…

关于 NLP 应用方向与深度训练的核心流程

文章目录 主流应用方向核心流程(5步)1.选定语言模型结构2.收集标注数据3.forward 正向传播4.backward 反向传播5.使用模型预测真实场景 主流应用方向 文本分类文本匹配序列标注生成式任务 核心流程(5步) 基本流程实现的先后顺序…

ShardingSphere 分库分表

中间件 常用中间件 MyCat 是基于 Proxy,它复写了 MySQL 协议,将 Mycat Server 伪装成⼀个 MySQL 数据库客户端所有的jdbc请求都必须要先交给MyCat,再有 MyCat转发到具体的真实服务器缺点是效率偏低,中间包装了⼀层代码⽆侵⼊性…

解决Android Studio 右上角Gradle不显示task

解决Android Studio 右上角Gradle不显示task_gradle中没有build task-CSDN博客 不正常的情况下 正常的情况下 解决方案 依次点击:File -> Settings -> Experimental -> 取消勾选 “Do not build Gradle task list during Gradle sync” 同步项目即可

[数据集][目标检测]基于yolov5增强数据集算法mosaic来扩充自己的数据集自动生成增强图片和对应标注无需重新标注

【算法介绍】 YOLOv5最引人注目的增强技术之一是马赛克增强,它将四张不同的图像拼接成一张图像。 思路:首先,从数据集中随机选择四张图像,然后将它们缩放、随机裁剪,并按马赛克模式拼接在一起。这种方式允许模型看到…

【逐行注释】MATLAB的程序,对比EKF(扩展卡尔曼滤波)和PF(粒子滤波)的滤波效果,附下载链接

文章目录 总述部分源代码运行结果扩展性 总述 本代码使用 M A T L A B MATLAB MATLAB实现了扩展卡尔曼滤波( E K F EKF EKF)和粒子滤波( P F PF PF)在状态估计中的对比分析。 主要功能包括: 参数设置:初始…

Android Studio 开发快速获取开发版和发布版SHA1和MD5

本文讲解Android Studio 开发中如何快速获取开发版和发布版SHA1和MD5。 一、获取开发版: 点击Android Studio右上角Gradle按钮,打开Gradle视图 找到项目-Tasks-signingReport 双击即可AndroidStudio底部 Run面板获取开发版SHA1和MD5 二、获取发布版:

《深入解析 Java 中的 ThreadLocal》

ThreadLocal 1.概述 ThreadLocal被称为线程局部变量,用于在线程中保存数据。由于在ThreadLocal中保存的数据仅属于当前线程,所以该变量对其他线程而言是隔离的,也就是说该变量是当前线程独有的变量。 ThreadLocal用于在同一个线程间&#…

STM32CubeIDE | 使用HAL库的ADC读取内部传感器温度

1、cubemx配置 1.1、系统配置 1.2、GPIO配置 PB2设置为“GPIO_Output” user label设置为“LED” 1.3、串口配置 模式选择为“Asynchronous”,其他默认 1.4、时钟树配置 全部保持默认 2、ADC配置 通道选择“Temperature Sensor Channel”,其他默认 …

基于STM32的Zeta型数控电源设计

本设计基于STM32F103C6T6为主控芯片,基于Zeta型DC/DC电源的拓扑结构设计一种数控电源。系统包含单片机主控模块、Zeta型升降压模块、驱动模块、电流采样模块、电压采样模块、OLED显示模块、电源模块及按键模块。用电流采样模块采集电流,电压采样模块采集…

Skyvern:基于LLM和CV的开源RPA

Skyvern 使用 LLM 和计算机视觉来自动化基于浏览器的工作流程。它提供了一个简单的 API 端点,可以完全自动化大量网站上的手动工作流程,从而取代脆弱或不可靠的自动化解决方案。 传统的浏览器自动化方法需要为网站编写自定义脚本,通常依赖于…

基于小安派AiPi-Eyes-Rx的N合1触摸屏游戏

基于小安派AiPi-Eyes-Rx的N合1触摸屏游戏 目前存在的游戏: 植物大战僵尸:demos/pvz羊了个羊:demos/yang消消乐:demos/xiaoxiaole华容道:demos/huarongdao PVZ功能展示可见: 羊了个羊: 消消…

在多态的方法调用中为什么会出现“左边编译左边运行”的现象?多态创建的对象到底是谁属于父类还是子类?通过深扒集合remove方法调用理解其原理

目录 “左边编译左边运行”的两个原因: 什么是“编译看左边,运行看右边”? 为什么会出现“左边编译左边运行”现象? 1. 子类没有重写父类的方法 2. 重载与重写的混淆(重难点) 问题:编译器是…

JAVA开源项目 体育馆管理系统 计算机毕业设计

本文项目编号 T 048 ,文末自助获取源码 \color{red}{T048,文末自助获取源码} T048,文末自助获取源码 目录 一、系统介绍二、演示录屏三、启动教程四、功能截图五、文案资料5.1 选题背景5.2 国内外研究现状5.3 可行性分析5.4 用例设计 六、核…

每日论文1——应用于65nm CMOS锁相环完全电流匹配的电荷泵

《A Charge Pump with Perfect Current Matching Applied to Phase-Locked Loop in 65nm CMOS》2021 IEEE 14th International Conference on ASIC 电荷泵PLL的结构框图如图,其中CP的充放电电流不匹配会引起PLL的频率误差和杂散。 传统的电荷泵结构在输出处的电平…

强烈推荐的10款企业文件加密软件|2024企业办公文件加密

随着信息安全威胁的不断增加,企业文件加密成为保护敏感数据的重要手段。在2024年,有多款文件加密软件可供选择,帮助企业提高数据安全性。以下是十款强烈推荐的企业文件加密软件。 1.安秉加密软件 安秉加密软件专为企业设计,主要用…

【Web】初识Web和Tomcat服务器

目录 前言 一、认识web 1. 软件架构模式 2. web资源 3. URL请求路径(统一资源定位符) 二、Tomcat服务器 1. 简介 2. tomcat服务器的目录结构 3.使用tomcat服务器启动失败的常见原因 3.1 端口冲突 3.2 jdk环境变量配置出错 三、使用Tomcat发布…