这就是命令,命令模式

简介: 命令模式:请求以命令的形式包裹在对象中,并传给调用对象。调用对象寻找可以处理该命令的合适的对象,并把该命令传给相应的对象,该对象执行命令。

0x01:命令模式简介


在软件设计中,我们经常需要向某些对象发送请求,但是并不知道请求的接收者是谁,也不知道被请求的操作是哪个, 我们只需在程序运行时指定具体的请求接收者即可,此时,可以使用命令模式来进行设计。


命令模式:请求以命令的形式包裹在对象中,并传给调用对象。调用对象寻找可以处理该命令的合适的对象,并把该命令传给相应的对象,该对象执行命令。


UML类图如下:


微信图片_20220502091443.png


主要角色分析如下:


Invoker:调用者,要求该命令执行这个请求,通常会持有命令对象,可以持有多个命令对象。这个是客户端真正触发命令并要求命令执行相应操作的地方,也就是相当于使用命令对象的入口。


Command:抽象命令,需要执行的所有命令都在这里声明,可以是接口或抽象类;


Receiver:接收者,真正执行命令的对象。知道如何实施与执行一个请求相关的操作,任何类都可能作为一个接收者,只要它能够实现命令要求实现的相应功能。


ConcreteCommand:命令接口实现对象,是“虚”的实现;通常会持有接收者,并调用接收者的功能来完成命令要执行的操作。


Client:创建具体的命令对象,并且设置命令对象的接收者。注意这个不是常规意义上的客户端,而是在组装命令对象和接收者。或许把这个Client称为装配者会更好理解,因为真正使用命令的客户端是从Invoker来触发执行。


0x02:命令模式的实现


Receiver:该角色就是干活的角色, 命令传递到这里就应该被执行


public class Receiver {
public void action() {
        System.out.println("命令执行了~~~");
    }
}


Command:声明执行操作的接口/抽象类


public abstract class Command {
protected Receiver receiver;
public Command(Receiver receiver) {
this.receiver = receiver;
    }
//执行命令的方法
abstract public void execute();
}


ConcreteCommand类:具体的Command,用于构造传递接收者,根据场景需求,具体的命令类也可能有多个


public class ConcreteCommand extends Command {
//构造传递接收者
    public ConcreteCommand(Receiver receiver) {
super(receiver);
    }
//必须实现一个命令
@Override
    public void execute() {
        receiver.action();
    }
}


Invoker类:接收命令,并执行命令


public class Invoker {
private Command command;
//接收命令
public void setCommand(Command command) {
this.command = command;
    }
//执行命令
public void executeCommand() {
        command.execute();
    }
}


命令模式测试代码:首先定义一个接收者,然后定义一个命令用于发送给接收者,最后再声明一个调用者,即可把命令交给调用者执行


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();
    }
}


0x03:命令模式在JDK与开源框架中的运用


多线程中的java.lang.Runable


JDK中的Runnable接口,Runnable 相当于命令模式中的抽象命令角色(Command)。Runnabl 中的run()方法就当于execute()方法。


@FunctionalInterface
public interface Runnable {
public abstract void run();
}


只要是实现了Runnable接口的类都被认为是一个线程,相当于命令模式中的具体命令角色(ConcreteCommand)


Thread就是调用者(Invoker),提供了start,join,interrupt等方法来控制“命令”也就是Runnable的执行。而Receiver则是让程序员可以自由与Runnale组合的抽象。

实际上调用线程的start()方法之后,就有资格去争抢CPU资源,而不需要编写获得CPU资源的逻辑。而线程抢到CPU资源后,就会执行run()方法中的内容,用Runnable接口把用户请求和CPU执行进行解耦。


工作流引擎Activiti


Activiti是一款优秀开源软件,通过阅读源码,不但可以了解工作流引擎执行的原理,还可以增加个人的编码功力。Activiti所有执行过程都是采用命令模式进行执行。

相关文章
|
新零售 Cloud Native Devops
坚持伙伴优先,阿里云颁发合作伙伴年度奖项
2023年4月26日,2023阿里云合作伙伴颁奖盛典在南京举行,阿里云向核心伙伴颁发年度奖项。
坚持伙伴优先,阿里云颁发合作伙伴年度奖项
|
存储 数据中心
什么是T3机房?T1/T2/T3/T4机房等级对比详解
我们在购买IDC服务时都会选择T3机房或者T4机房,那么什么是T3机房?T3机房和T4机房有什么区别?服务器百科网来说说T1/T2/T3/T4机房等级对比详解: IDC机房等级划分 IDC机房的等级划分是根据《数据中心电信基础设施标准》而定的,它是美国国家标准学会(ANSI)颁布的,它将IDC数据中心(大型的设备和管理都比较完善的机房可以称为数据中心)基础设施的可用性定义了四种不同等级,即Tier 1、Tier 2、Tier 3和Tier 4四个等级。
19028 0
|
10月前
|
自然语言处理 人机交互 数据库
TransferTOD:利用LLM解决TOD系统在域外场景槽位难以泛化的问题
任务型对话系统旨在高效处理任务导向的对话,如何利用任务型对话系统准确、高效、合理地完成信息采集的工作一直是一项关键且具有挑战性的任务。
400 18
|
11月前
|
网络协议 应用服务中间件 网络安全
免费泛域名https证书教程—无限免费续签
随着互联网安全意识提升,越来越多网站采用HTTPS协议。本文介绍如何通过JoySSL轻松获取并实现免费泛域名SSL证书的无限续签。JoySSL提供永久免费通配符SSL证书,支持无限制域名申请及自动续签,全中文界面适合国内用户。教程涵盖注册账号、选择证书类型、验证域名所有权、下载与安装证书以及设置自动续签等步骤,帮助网站简化SSL证书管理流程,确保长期安全性。
1017 20
|
安全 Ubuntu Linux
6 个受欢迎且好用的轻量级Linux桌面环境
Linux被认为是最安全的系统,但这并不意味着它不受恶意软件或其他安全漏洞的侵害。Linux系统的使用范围非常广泛,因此防范潜在威胁至关重要。在这里,将探索 2024 年适用于 Linux 的最佳防病毒软件。根据评级、功能以及与其他 Linux 发行版的兼容性列出了十款最佳防病毒软件,内容仅供分享,不做其它用途。
3939 1
6 个受欢迎且好用的轻量级Linux桌面环境
|
监控 BI 数据处理
RPA技术在金融领域的应用?
【8月更文挑战第4天】RPA技术在金融领域的应用?
321 1
|
网络协议 安全 数据安全/隐私保护
|
存储 安全 算法
物联网中的数据加密技术
【6月更文挑战第1天】物联网中的数据加密技术
1718 0
|
物联网 开发工具 C++
AliOS Things 的 ESP32 应用开发流程
本文介绍 Windows 下基于 AliOS Things 的 ESP32 应用开发流程,包括环境搭建、程序编译、固件烧写。
10461 5