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

2024-01-23 08:12

本文主要是介绍笨蛋学设计模式行为型模式-命令模式【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总结

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

这篇关于笨蛋学设计模式行为型模式-命令模式【19】的文章就介绍到这儿,希望我们推荐的文章对编程师们有所帮助!



http://www.chinasem.cn/article/635765

相关文章

Java设计模式---迭代器模式(Iterator)解读

《Java设计模式---迭代器模式(Iterator)解读》:本文主要介绍Java设计模式---迭代器模式(Iterator),具有很好的参考价值,希望对大家有所帮助,如有错误或未考虑完全的地方,... 目录1、迭代器(Iterator)1.1、结构1.2、常用方法1.3、本质1、解耦集合与遍历逻辑2、统一

Java 线程安全与 volatile与单例模式问题及解决方案

《Java线程安全与volatile与单例模式问题及解决方案》文章主要讲解线程安全问题的五个成因(调度随机、变量修改、非原子操作、内存可见性、指令重排序)及解决方案,强调使用volatile关键字... 目录什么是线程安全线程安全问题的产生与解决方案线程的调度是随机的多个线程对同一个变量进行修改线程的修改操

postgresql数据库基本操作及命令详解

《postgresql数据库基本操作及命令详解》本文介绍了PostgreSQL数据库的基础操作,包括连接、创建、查看数据库,表的增删改查、索引管理、备份恢复及退出命令,适用于数据库管理和开发实践,感兴... 目录1. 连接 PostgreSQL 数据库2. 创建数据库3. 查看当前数据库4. 查看所有数据库

linux重启命令有哪些? 7个实用的Linux系统重启命令汇总

《linux重启命令有哪些?7个实用的Linux系统重启命令汇总》Linux系统提供了多种重启命令,常用的包括shutdown-r、reboot、init6等,不同命令适用于不同场景,本文将详细... 在管理和维护 linux 服务器时,完成系统更新、故障排查或日常维护后,重启系统往往是必不可少的步骤。本文

nginx启动命令和默认配置文件的使用

《nginx启动命令和默认配置文件的使用》:本文主要介绍nginx启动命令和默认配置文件的使用,具有很好的参考价值,希望对大家有所帮助,如有错误或未考虑完全的地方,望不吝赐教... 目录常见命令nginx.conf配置文件location匹配规则图片服务器总结常见命令# 默认配置文件启动./nginx

Redis Cluster模式配置

《RedisCluster模式配置》:本文主要介绍RedisCluster模式配置,本文给大家介绍的非常详细,对大家的学习或工作具有一定的参考借鉴价值,需要的朋友参考下吧... 目录分片 一、分片的本质与核心价值二、分片实现方案对比 ‌三、分片算法详解1. ‌范围分片(顺序分片)‌2. ‌哈希分片3. ‌虚

基于Python实现一个Windows Tree命令工具

《基于Python实现一个WindowsTree命令工具》今天想要在Windows平台的CMD命令终端窗口中使用像Linux下的tree命令,打印一下目录结构层级树,然而还真有tree命令,但是发现... 目录引言实现代码使用说明可用选项示例用法功能特点添加到环境变量方法一:创建批处理文件并添加到PATH1

Java -jar命令如何运行外部依赖JAR包

《Java-jar命令如何运行外部依赖JAR包》在Java应用部署中,java-jar命令是启动可执行JAR包的标准方式,但当应用需要依赖外部JAR文件时,直接使用java-jar会面临类加载困... 目录引言:外部依赖JAR的必要性一、问题本质:类加载机制的限制1. Java -jar的默认行为2. 类加

git stash命令基本用法详解

《gitstash命令基本用法详解》gitstash是Git中一个非常有用的命令,它可以临时保存当前工作区的修改,让你可以切换到其他分支或者处理其他任务,而不需要提交这些还未完成的修改,这篇文章主要... 目录一、基本用法1. 保存当前修改(包括暂存区和工作区的内容)2. 查看保存了哪些 stash3. 恢

java -jar命令运行 jar包时运行外部依赖jar包的场景分析

《java-jar命令运行jar包时运行外部依赖jar包的场景分析》:本文主要介绍java-jar命令运行jar包时运行外部依赖jar包的场景分析,本文给大家介绍的非常详细,对大家的学习或工作... 目录Java -jar命令运行 jar包时如何运行外部依赖jar包场景:解决:方法一、启动参数添加: -Xb