笨蛋学设计模式行为型模式-命令模式【19】

行为型模式-命令模式

    • 8.6命令模式
      • 8.6.1概念
      • 8.6.2场景
      • 8.6.3优势 / 劣势
      • 8.6.4命令模式可分为
      • 8.6.5命令模式
      • 8.6.6实战
        • 8.6.6.1题目描述
        • 8.6.6.2输入描述
        • 8.6.6.3输出描述
        • 8.6.6.4代码
      • 8.6.7总结

8.6命令模式

8.6.1概念

​ 命令模式允许将请求封装成一个对象(命令对象,包含执行操作所需地所有信息),并将命令对象按照一定的顺序存储在队列中,然后再逐一调用执行,这些命令可以支持反向操作,进行撤销和重做。这样发送者就只需要触发命令就可以完成操作,不需要知道接受者的具体操作,从而实现两者间的解耦

8.6.2场景

​ 在餐饮业中,命令模式可以用于实现订单的处理流程。例如在餐厅中,当我们在客户端或者小程序上进行点单,客户端 / 小程序会将我们在上面下的订单请求封装成为一个对象,通过发送命令给后厨的工作人员上,而他们就会根据我们下的具体订单进行菜品备菜、菜品制作、菜品上菜等一系列操作。

8.6.3优势 / 劣势

  • 降低系统的耦合度:将请求的发送者和接收者解耦
  • 提高系统扩展性:可以方便地扩展新的命令和接收者,提高系统的扩展力
  • 增加请求队列:可以很容易地增加一个请求队列,以便在需要时处理或延迟处理请求
  • 支持撤销操作:通过记录一系列命令,可以很轻松地回溯并撤销之前地操作

  • 增加系统的复杂性:需要创建多个类和对象
  • 执行顺序不保证:不能保证命令的执行顺序

8.6.4命令模式可分为

  • 命令接口Command:接口或抽象类,定义执行操作的接口
  • 具体命令类ConcreteCommand:实现命令接口,执行具体操作,在调用execute方法时"接收者对象"根据命令完成具体的任务,比如遥控器中的"开机","关机"命令
  • 接收者类Receiver:接受并执行命令的对象,可以是任何对象,遥控器可以控制空调,也可以控制电视机,电视机和空调负责执行具体操作,是接收者
  • 调用者类Invoker:发起请求的对象,有一个将命令作为参数传递的方法。它不关心命令的具体实现,只负责调用命令对象的execute()方法来传递请求,在本例中,控制遥控器的"人"就是调用者
  • 客户端:创建具体的命令对象和接收者对象,然后将它们组装起来

8.6.5命令模式

package com.technologystatck.designpattern.mode.command;import java.util.*;public class Commands {public static void main(String[] args) {Receiver receiver = new Receiver();ConcreteCommand command = new ConcreteCommand(receiver);new Invoker(command).executeCommand();}
}
//定义执行操作的接口,包含一个execute方法,有时还会包括unExecute方法,表示撤销命令
interface Command{//执行方法void execute();//撤销方法void undo();
}//实现命令接口,执行具体的操作
class ConcreteCommand implements Command{//接收者对象private Receiver receiver;public ConcreteCommand(Receiver receiver) {this.receiver = receiver;}@Overridepublic void execute() {receiver.action();}@Overridepublic void undo() {receiver.unAction();}
}//定义接受者类,知道如何实施与执行一个请求相关的操作
class Receiver{public void action(){//执行操作}public void unAction(){//撤销操作}
}
//定义调用者类,调用命令对象执行请求
class Invoker{private Command command;public Invoker(Command command) {this.command = command;}public void executeCommand(){command.execute();}
}
//调用者类可以维护一个命令队列或者撤销栈,以支持批处理和撤销命令
class Invoker{//命令队列private Queue<Command> commandQueue;//撤销栈private Stack<Command> undoStack;public Invoker(Queue<Command> commandQueue, Stack<Command> undoStack) {this.commandQueue = new LinkedList<>();this.undoStack = new Stack<>();}//设置命令并执行public void setAndExecuteCommand(Command command){command.execute();commandQueue.offer(command);undoStack.push(command);}//撤销上一个命令public void undoLastCommand(){if(!undoStack.isEmpty()){Command lastCommand = undoStack.pop();//命令类实现undo方法lastCommand.undo();commandQueue.remove(lastCommand);}else{System.out.println("No command to undo.");}}//执行命令队列中的所有命令public void executeCommandsInQueue(){for (Command command : commandQueue) {command.execute();}}
}

8.6.6实战

8.6.6.1题目描述

小明去奶茶店买奶茶,他可以通过在自助点餐机上来点不同的饮品,请你使用命令模式设计一个程序,模拟这个自助点餐系统的功能。

8.6.6.2输入描述
  • 第一行是一个整数 n(1 ≤ n ≤ 100),表示点单的数量。
  • 接下来的 n 行,每行包含一个字符串,表示点餐的饮品名称。
8.6.6.3输出描述

输出执行完所有点单后的制作情况,每行输出一种饮品的制作情况。如果制作完成,输出 “XXX is ready!”,其中 XXX 表示饮品名称。

8.6.6.4代码
package com.technologystatck.designpattern.mode.command;import java.util.Scanner;public class Test {public static void main(String[] args) {Scanner scanner = new Scanner(System.in);//创建接收者和命令对象DrinkMaker drinkMaker = new DrinkMaker();//读取命令数量int nums=scanner.nextInt();scanner.nextLine();while(nums-- > 0){//读取命令String drinkName=scanner.next();//创建命令对象OrderCommand command = new OrderCommand(drinkName, drinkMaker);//执行命令OrderMachine orderMachine = new OrderMachine();orderMachine.setCommand(command);orderMachine.executeOrder();}scanner.close();}
}//定义执行操作的命令订单接口
interface Command{void execute();
}//定义具体命令类实现点餐
class OrderCommand implements Command{//饮料名称private String drinkName;//具体的饮料制作者private DrinkMaker drinkMaker;public OrderCommand(String drinkName, DrinkMaker drinkMaker) {this.drinkName = drinkName;this.drinkMaker = drinkMaker;}@Overridepublic void execute() {drinkMaker.makeDrink(drinkName);}
}//接收者类-制作饮料
class DrinkMaker{public void makeDrink(String drinkName){System.out.println(drinkName+" is ready!");}
}//调用者类-点餐机
class OrderMachine{private Command command;public void setCommand(Command command) {this.command = command;}//执行下单方法public void executeOrder(){command.execute();}
}

8.6.7总结

  • 优点:方便扩展新的命令和接收者,还可以撤销操作,增加系统的灵活性和可维护性
  • 总结:将请求封装成一个对象,通过具体命令类、调用者、接收者以此来完成相关操作
  • 场景:适用于需要实现撤销操作,需要保证事务一致性等场景

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

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

相关文章

上门回收小程序,打造回收新模式

近年来&#xff0c;我国一直秉持着环保绿色的发展理念&#xff0c;为了减少资源浪费&#xff0c;旧物回收成为了人们处理废弃物品的方式。目前&#xff0c;我国回收市场规模大约能达到3.58亿元&#xff0c;在我国经济的稳定增长和环保意识的提高下&#xff0c;回收市场规模还将…

Spring事件发布ApplicationEventPublisher原理

借鉴&#xff1a;https://blog.csdn.net/zxfhahaha/article/details/112558429 https://blog.csdn.net/qq_46940224/article/details/131043987 https://blog.csdn.net/weixin_37672801/article/details/128803430 https://www.cnblogs.com/shamo89/p/15715091.html https://bl…

科技、文化与旅游的融合创新:智慧文旅的未来之路

在当今社会&#xff0c;科技、文化与旅游的融合已经成为文旅产业转型升级的重要趋势。这种融合不仅有助于提升文旅产业的核心竞争力&#xff0c;更有助于推动产业的数字化转型和可持续发展。 本文将深入探讨科技、文化与旅游的融合创新&#xff0c;以及智慧文旅场景的解决方案…

【C++语言1】基本语法

前言 &#x1f493;作者简介&#xff1a; 加油&#xff0c;旭杏&#xff0c;目前大二&#xff0c;正在学习C&#xff0c;数据结构等&#x1f440; &#x1f493;作者主页&#xff1a;加油&#xff0c;旭杏的主页&#x1f440; ⏩本文收录在&#xff1a;再识C进阶的专栏&#x1…

代码+视频R语言绘制逆概率加权后的基线表

基于 PS &#xff08;倾向评分&#xff09;的逆概率加权(IPTW )法首先由&#xff32;osenbaum作为一种以模型为基础的直接标准化法提出&#xff0c;属于边际结构模型。简单来说&#xff0c;就是把许多协变量和混杂因素打包成一个概率并进行加权&#xff0c;这样的话&#xff0c…

【GoLang入门教程】Go语言工程结构详述

程序员裁员潮&#xff1a;技术变革下的职业危机 文章目录 程序员裁员潮&#xff1a;技术变革下的职业危机前言总结:专栏集锦强烈推荐写在最后 前些天发现了一个巨牛的人工智能学习网站&#xff0c;通俗易懂&#xff0c;风趣幽默&#xff0c;忍不住分享一下给大家。点击跳转到网…

3d音响按键怎么建立模型---模大狮模型网

要建立3D音响按键的模型&#xff0c;您可以按照以下步骤进行&#xff1a; 选择建模软件&#xff1a;首先&#xff0c;选择一个三维建模软件&#xff0c;如Blender、3ds Max或Maya。这些软件都提供了丰富的建模工具和功能&#xff0c;适合用于创建复杂的三维模型。 参考图像&am…

java SSM自助快递服务平台myeclipse开发mysql数据库springMVC模式java编程计算机网页设计

一、源码特点 java SSM自助快递服务平台是一套完善的web设计系统&#xff08;系统采用SSM框架进行设计开发&#xff0c;springspringMVCmybatis&#xff09;&#xff0c;对理解JSP java编程开发语言有帮助&#xff0c;系统具有完整的源代 码和数据库&#xff0c;系统主要采…

DophineScheduler通俗版

1.DophineScheduler的架构 ZooKeeper&#xff1a; AlertServer&#xff1a; UI&#xff1a; ApiServer&#xff1a; 一个租户下可以有多个用户&#xff1b;一个用户可以有多个项目一个项目可以有多个工作流定义&#xff0c;每个工作流定义只属于一个项目&#xff1b;一个租户可…

人工智能原理实验4(2)——贝叶斯、决策求解汽车评估数据集

&#x1f9e1;&#x1f9e1;实验内容&#x1f9e1;&#x1f9e1; 汽车数据集 车子具有 buying,maint,doors,persons,lug_boot and safety六种属性&#xff0c;而车子的好坏分为uncc,ucc,good and vgood四种。 &#x1f9e1;&#x1f9e1;贝叶斯求解&#x1f9e1;&#x1f9e1;…

Redis——RDB持久化

前言 Redis是一个键值对数据库服务器&#xff0c;服务器中通常包含任意个非空数据库&#xff0c;而每个非空数据库中又可以包含任意个键值对&#xff0c;为了方便起见&#xff0c;我们将服务器中的非空数据库以及它们的键值对统称为数据库状态。 因为Redis数据库是内存数据库&a…

Java/Python/Go不同开发语言在进程、线程和协程的设计差异

Java/Python/Go不同开发语言在进程、线程和协程的设计差异 1. 进程、线程和协程上的差异1.1 进程、线程、协程的定义1.2 进程、线程、协程的差异1.3 进程、线程、协程的内存成本1.4 进程、线程、协程的切换成本 2. 线程、协程之间的通信和协作方式2.1 python如何实现线程通信&a…

大模型实战营Day6 笔记

本期主题为&#xff1a; 为何测评&#xff0c;因场景众多&#xff0c;需要统一的标准&#xff1a; 评测的意义&#xff1a; 传统NLP的一些评测需要&#xff1a; 到了大模型时代&#xff0c;需要评测的就更多了&#xff1a; 客观评测&#xff1a; 有些主观题可以用模型评价…

cdh6.3.2的hive配udf

背景 大数据平台的租户要使用udf&#xff0c;他们用beeline连接&#xff0c; 意味着要通过hs2&#xff0c;但如果有多个hs2&#xff0c;各个hs2之间不能共享&#xff0c;需要先把文件传到hdfs&#xff0c;然后手动在各hs2上create function。之后就可以永久使用了&#xff0c;…

docker配置node项目

首先在项目根目录创建Dockerfile FROM node:18.19RUN mkdir /appCOPY . /appWORKDIR /appRUN npm installEXPOSE 8081CMD ["npm","run","start"]添加.dockerignore文件 /dist /node_moduleslogs *.log npm-debug.log* yarn-debug.log* yarn-er…

从零开始的OpenGL光栅化渲染器构建3-法线贴图和视差贴图

前言 我们可以用一张纹理贴图来表现物体表面的基础反射颜色&#xff0c;也可以用一张镜面反射贴图&#xff0c;来指派表面是否产生高光。除此之外&#xff0c;我们可以用贴图来存储表面的法线信息&#xff0c;以及高度信息&#xff0c;从而让渲染效果更加精细。 法线贴图 我…

通过浏览器URL地址,5分钟内渗透你的网站!很刑很可拷!

今天我来带大家简单渗透一个小破站&#xff0c;通过这个案例&#xff0c;让你深入了解为什么很多公司都需要紧急修复各个中间件的漏洞以及进行URL解析拦截等重要操作。这些措施的目的是为了保护网站和系统的安全性。如果不及时升级和修复漏洞&#xff0c;你就等着被黑客攻击吧&…

【LeetCode209】 长度最小的子数组

209. 长度最小的子数组 滑动窗口型双指针 给定一个含有 n 个正整数的数组和一个正整数 target 。 找出该数组中满足其总和大于等于 target 的长度最小的 连续子数组 [numsl, numsl1, …, numsr-1, numsr] &#xff0c;并返回其长度。如果不存在符合条件的子数组&#xff0c;…

浮点数详解

目录 1.概述 2.浮点数的编码方式 2.1.float类型的IEEE编码 2.2.double类型的IEEE编码 2.3.现场问题 2.4.总结 1.概述 计算机也需要运算和存储数学中的实数。在计算机的发展过程中&#xff0c;曾产生过多种存储实数的方式&#xff0c;有的现在已经很少使用了。不管如何存储…

HBase学习五:运维排障之宕机恢复

1 简介 HBase系统中主要有两类服务进程:Master进程以及RegionServer进程。Master主要负责集群管理调度,在实际生产线上并没有非常大的压力,因此发生软件层面故障的概率非常低。RegionServer主要负责用户的读写服务,进程中包含很多缓存组件以及与HDFS交互的组件,实际生产线…