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

设计模式(19)命令模式

一、介绍:

1、定义:命令模式(Command Pattern)是一种行为设计模式,它将请求封装为一个对象,从而使你可以使用不同的请求对客户端进行参数化。命令模式还支持请求的排队、记录日志、撤销操作等功能。

2、组成结构:

(1)命令接口(Command):定义执行命令的方法,可以是抽象类或接口。

public interface Command {void execute();
}

(2)具体命令类(Concrete Command):实现命令接口,封装了具体的请求和接收者,负责执行请求。

/*** 具体的命令实现*/
public class ConcreteCommand implements Command {/*** 持有相应的接收者对象*/private Receiver receiver = null;/*** 构造方法,传入相应的接收者对象* * @param receiver 相应的接收者对象*/public ConcreteCommand(Receiver receiver) {this.receiver = receiver;}/*** 执行命令*/@Overridepublic void execute() {// 通常会转调接收者对象的相应方法,让接收者来真正执行功能receiver.action();}}

(3)接收者类(Receiver):命令接受者对象,定义了命令接受者可以做的事情。执行实际的操作,命令对象将请求委托给接收者来执行。

public class Receiver {public void action() {System.out.println("执行具体操作");}
}

(4)调用者类(Invoker):Invoker类是具体命令的接收者,用于接收客户的所有命令,然后将命令转达给执行者,执行这些命令。

public class Invoker {private Command command;public void setCommand(Command command) {this.command = command;}public void executeCommand() {command.execute();}
}

客户端(Client):创建具体的命令对象,并将其分配给调用者来执行。

public class Client {public static void main(String[] args) {// 创建接收者Receiver receiver = new Receiver();// 创建命令对象,设定它的接收者Command command = new ConcreteCommand(receiver);// 创建调用者,把命令对象设置进去Invoker invoker = new Invoker();invoker.setCommand(command);// 调用者调用命令invoker.executeCommand();}
}

3、优点

  • 能够比较容易的设计一个命令队列
  • 在需要的情况下,可以比较容易地将命令记入日志
  • 允许接收请求的一方决定是否要解决请求
  • 可以容易的实现对请求的撤销和重做
  • 容易扩展新的命令类
  • 能够把请求一个操作的对象,与知道怎么执行一个操作的对象分隔开

二、demo:

1、点餐:服务员充当命令委托角色,在顾客和厨师之间松耦合

(1)命令:

//顾客抽象命令
public abstract class Command {public Integer count;public Integer getCount() {return count;}public void setCount(Integer count) {this.count = count;}protected Cook receiver;public Command(Cook receiver,int count) {this.receiver = receiver;this.count = count;}public abstract void execute();
}//具体命令1
public class BakeBeefCommand extends Command {public BakeBeefCommand(Cook receiver,int count) {super(receiver,count);}@Overridepublic void execute() {receiver.bakeBeef();}
}//具体命令2
public class BakeMuttonCommand extends  Command{public BakeMuttonCommand(Cook receiver,int count) {super(receiver,count);}@Overridepublic void execute() {receiver.bakeMutton();}
}

(2)命令实际接收者 厨师

public class Cook {public void bakeMutton(){System.out.println("烤羊肉");}public void bakeBeef(){System.out.println("烤牛肉");}
}

(3)命令中转 服务员

public class Waiter {private List<Command> orders= new ArrayList<>();public void setOrder(Command command) {if(command.getCount() < 5){System.err.println("点餐失败,一份数量最小为5,count="+command.getCount());}else{System.out.println("点餐成功,记录日志,count="+command.getCount());this.orders.add(command);}}public void cancleOrder(Command command) {System.out.println("取消成功,记录日志,count="+command.getCount());this.orders.remove(command);}public void executeCommand(){System.out.println("***点餐结束***");for (Command comm : orders) {comm.execute();}}
}

客户端

public static void main(String[] args) {Cook receiver = new Cook();Waiter waiter = new Waiter();Command muttonCommand = new BakeMuttonCommand(receiver,1);waiter.setOrder(muttonCommand);muttonCommand = new BakeMuttonCommand(receiver,5);waiter.setOrder(muttonCommand);Command beefCommand = new BakeBeefCommand(receiver,6);waiter.setOrder(beefCommand);beefCommand = new BakeBeefCommand(receiver,7);waiter.setOrder(beefCommand);//临时取消waiter.cancleOrder(beefCommand);//全部点餐结束后执行waiter.executeCommand();}输出:
点餐失败,一份数量最小为5,count=1
点餐成功,记录日志,count=5
点餐成功,记录日志,count=6
点餐成功,记录日志,count=7
取消成功,记录日志,count=7
***点餐结束***
烤羊肉
烤牛肉
http://www.lryc.cn/news/213473.html

相关文章:

  • QModelIndex 与QStandardItem相互转换
  • Linux - 进程地址空间
  • 系统架构设计师-第16章-嵌入式系统架构设计理论与实践-软考学习笔记
  • pod进阶
  • 系列四十七、Spring的事务传播行为案例演示(七)#NOT_SUPPORTED
  • 54.RabbitMQ快速实战以及核心概念详解
  • Qt TreeView 设置节点不可编辑
  • python django获取某个角色的某个数据和——例如:获取所有订单的应付金额总和
  • 如何在React项目中引用less
  • NUXT前端服务端渲染技术框架
  • 力扣每日一题90:子集
  • 「linux基础」上传代码到github/gitee
  • Hafnium总体考虑
  • C#__对Json文件的解析和序列化
  • 如果一定要在C++和JAVA中选择,是C++还是java?
  • 如何运行深度学习项目代码
  • C语言 每日一题 day9
  • 通讯网关软件032——利用CommGate X2OPC实现OPC客户端访问Modbus TCP设备
  • [计算机提升] 查看系统软件
  • 【mysql】单表数据量过大解决方案
  • Kafka - 3.x 消费者 生产经验不完全指北
  • UDP网络编程的接受与发送信息
  • RK3588开发笔记-USB3.0接口调试
  • AI绘画|midjourney入门保姆教程,30秒出专业大片,国内直接使用
  • 阿里发布AI编码助手:通义灵码,兼容 VS Code、IDEA等主流编程工具
  • 【Linux】-进程控制(深度理解写时拷贝、exit函数、return的含义以及makefile编译多个程序)-进程创建、进程终止、进程等待、进程程序替换
  • 【mfc/VS2022】计图实验:绘图工具设计知识笔记3
  • Leetcode—1488.避免洪水泛滥【中等】
  • CSS与基本选择器
  • 回归算法|长短期记忆网络LSTM及其优化实现