命令模式简介

2023-09-19 09:11:57

概念

命令模式是一种行为设计模式,它将请求封装成一个对象,从而允许您将不同的请求参数化、队列化,并且能够在不同的时间点执行。通过引入命令对象(Command)来解耦发送者(Invoker)和接收者(Receiver),使得发送者无需知道具体的接收者或操作细节。命令对象封装了一系列操作,并提供了一个统一的方法(如execute()),以便调用这些操作。

特点

  1. 解耦性:命令模式将发送者与接收者之间解耦,使得它们可以独立演化。
  2. 可扩展性:可以方便地添加新的命令类和接收类,而无需修改现有代码。
  3. 可撤销/重做:由于每个命令都包含了执行和撤销操作,因此可以轻松地实现撤销、重做等功能。
  4. 容易组合:多个简单命令可以组合成复杂命令,在需要时进行灵活组合。

优点

  1. 降低系统的耦合度。发送者与接收者之间不存在直接关联关系。
  2. 更好地支持撤销、重做等功能。每个具体命令断言了相关操作及其撤销操作。
  3. 更好地支持日志和事务。可以记录命令的执行过程,以及在需要时进行回滚。

缺点

  1. 可能会导致类爆炸。每个具体命令都需要一个对应的接收者类。
  2. 命令模式增加了系统的复杂性,因为它引入了额外的抽象层次。

适用场景

  1. 需要将请求参数化、队列滑,并希望能够在不同时间执行。
  2. 需要支持撤销、重做等功能。
  3. 需要实现日志记录、事务管理等功能。

实现方式

  1. 定义一个抽象命令(Command)接口或抽象类,其中包含一个execute()方法用于执行命令。
  2. 创建具体命令类,实现抽象命令接口或继承抽象命令类,并在其中编写具体操作逻辑及其撤销逻辑。
  3. 定义接收者(Receiver)类,该类包含真正执行操作的方法。
  4. 创建调用者(Invoker)对象,在其中维护一系列命令对象,并通过调用execute()方法来触发相应的操作。

实现代码

import java.util.ArrayList;
import java.util.List;

// 抽象命令接口
interface Command {
    void execute();
}

// 具体命令类1
class ConcreteCommand1 implements Command {
    private Receiver receiver;

    public ConcreteCommand1(Receiver receiver) {
        this.receiver = receiver;
    }

    @Override
    public void execute() {
        receiver.action1();
    }
}

// 具体命令类2
class ConcreteCommand2 implements Command {
    private Receiver receiver;

    public ConcreteCommand2(Receiver receiver) {
        this.receiver = receiver;
    }

    @Override
    public void execute() {
        receiver.action2();
    }
}

// 接收者类
class Receiver {
    public void action1() {
        System.out.println("执行操作1");
    }

    public void action2() {
        System.out.println("执行操作2");
    }
}

// 调用者类/发送者类/Invoker类
class Invoker {
    private List<Command> commands = new ArrayList<>();

    // 添加命令到队列中
    public void addCommand(Command command) {
        commands.add(command);
    }

    // 执行所有的命令
    public void executeCommands() {
        for (Command command : commands) {
            command.execute();
        }
        commands.clear(); // 清空已执行的命令列表,可选操作。
    }
}

public class Main {

    public static void main(String[] args) {
        // 创建接收者对象
        Receiver receiver = new Receiver();

        // 创建具体命令对象并指定接收者
        Command command1 = new ConcreteCommand1(receiver);
        Command command2 = new ConcreteCommand2(receiver);

        // 创建调用者对象,并添加命令到队列中
        Invoker invoker = new Invoker();
        invoker.addCommand(command1);
        invoker.addCommand(command2);

        // 执行所有命令
        invoker.executeCommands();
    }


}

在上述代码中,我们定义了一个抽象的Command接口,其中包含了一个execute()方法。然后创建了两个具体的命令类:ConcreteCommand1`ConcreteCommand2,它们实现了Command接口并重写了execute()`方法。这些具体的命令类将调用接收者类中的不同操作。

在接收者类中,我们定义了两个操作:action1()action2()

最后,我们创建了一个调用者类/发送者类/Invoker类。它维护一个命令队列,并提供添加命令和执行所有命令的方法。当调用执行所有命令的方法时,它会依次执行每个命令。

通过使用命令模式,可以将请求发送方与接收方解耦,并且可以轻松地添加新的具体命令而无需修改现有代码。此外,由于每个具体的命令都是独立封装的对象,因此可以轻松地进行参数化配置和传递。

更多推荐

机器学习技术(十)——决策树算法实操,基于运营商过往数据对用户离网情况进行预测

机器学习技术(十)——决策树算法实操文章目录机器学习技术(十)——决策树算法实操一、引言二、数据集介绍三、导入相关依赖库四、读取并查看数据1、读取数据2、查看数据五、数据预处理1、选择数据2、数据转码六、建模与参数优化1、训练模型2、评估模型3、调参优化七、模型可视化八、决策树实操总结一、引言决策树部分主要包含基于py

django_model_一对一映射

settings相关配置#settings.py...DATABASES={'default':{'ENGINE':'django.db.backends.mysql','NAME':'djangos','USER':'root','PASSWORD':'990212','HOST':'localhost','PORT

【TCP】滑动窗口、流量控制 以及拥塞控制

滑动窗口、流量控制以及拥塞控制1.滑动窗口(效率机制)2.流量控制(安全机制)3.拥塞控制(安全机制)1.滑动窗口(效率机制)TCP使用确认应答策略,对每一个发送的数据段,都要给一个ACK确认应答。收到ACK后再发送下一个数据段。这样做有一个比较大的缺点,就是性能较差。尤其是数据往返的时间较长的时候。既然这样一发一收的

大厂超全安全测试--关于安全测试的分类及如何测试

安全测试(总结)1.jsonNP劫持(其实json劫持和jsonNP劫持属于CSRF跨站请求伪造)的攻击范畴,解决方法和CSRF一样定义:构造带有jsonp接口的恶意页面发给用户点击,从而将用户的敏感信息通过jsonp接口传输到攻击者服务器json语法规则:数据在名称/值对中、数据由逗号分隔、花括号保存对象、方括号保存

循环神经网络——中篇【深度学习】【PyTorch】【d2l】

文章目录6、循环神经网络6.4、循环神经网络(`RNN`)6.4.1、理论部分6.4.2、代码实现6.5、长短期记忆网络(`LSTM`)6.5.1、理论部分6.5.2、代码实现6.6、门控循环单元(`GRU`)6.6.1、理论部分6.6.2、代码实现6、循环神经网络6.4、循环神经网络(RNN)6.4.1、理论部分原理

18.3 【Linux】登录文件的轮替(logrotate)

18.3.1logrotate的配置文件logrotate主要是针对登录文件来进行轮替的动作,他必须要记载“在什么状态下才将登录文件进行轮替”的设置。logrotate这个程序的参数配置文件在:/etc/logrotate.conf/etc/logrotate.d/logrotate.conf才是主要的参数文件,至于l

Android官方推荐 无需向应用授予的照片选择器工具

官网链接Photopicker|AndroidDevelopers不能跳转链接看这Photopicker照片选择器对话框会显示在您的设备上的媒体文件中。选择一张照片与应用程序分享。图1.照片选择器提供了一个直观的用户界面,用于与您的应用程序分享照片。照片选择器提供了一个可浏览、可搜索的界面,向用户呈现了他们的媒体库,按

个人电脑(windows、mac)安装Docker Desktop

目录什么是Docker?DockerDesktop在个人电脑上的作用安装DockerDesktop在学习大数据、人工智能等技术时,常常需要安装相应软件来支持我们的学习和实践。然而,很多这样的软件更适合在Linux环境下进行部署和运行。通过在个人电脑安装DockerDesktop可以解决该类问题,在个人电脑上轻松地搭建软

[hive]搭建hive3.1.2hiveserver2高可用可hive metastore高可用

参考:Apachehive3.1.2从单机到高可用部署HiveServer2高可用Metastore高可用hiveonsparkhiveserver2webUI高可用集群启动脚本_薛定谔的猫不吃猫粮的博客-CSDN博客没用里头的hiveonspark,测试后发现版本冲突一、Hive集群规划(蓝色部分)ck1ck2ck3

SpringCloud OpenFeign--声明式WebService 客户端

😀前言本篇博文是关于SpringCloudOpenFeign的基本介绍,希望你能够喜欢🏠个人主页:晨犀主页🧑个人简介:大家好,我是晨犀,希望我的文章可以帮助到大家,您的满意是我的动力😉😉💕欢迎大家:这里是CSDN,我总结知识的地方,欢迎来到我的博客,感谢大家的观看🥰如果文章有什么需要改进的地方还请大佬不吝

2023华为OD统一考试(B卷)题库清单(按算法分类),如果你时间紧迫,就按这个刷

目录专栏导读华为OD机试算法题太多了,知识点繁杂,如何刷题更有效率呢?一、逻辑分析二、数据结构1、线性表①数组②双指针2、map与list3、优先队列4、滑动窗口5、二叉树6、并查集7、栈三、算法1、基础算法①贪心算法②二分查找③分治递归④搜索算法⑤排序算法2、字符串①KMP②字符串处理③正则表达式3、深度优先搜索①广

热文推荐