命令模式(行为型)

news2024/11/23 18:45:13

目录

一、前言

二、命令模式

三、总结


一、前言

        命令模式(Command Pattern)是一种行为型设计模式,命令模式将一个请求封装为一个对象,从而可以用不同的请求对客户进行参数化;对请求排队或记录请求日志,以及支持可撤销的操作。 

        命令模式由以下角色组成:

Command(命令):

该角色定义了执行操作的接口。通常包含一个执行操作的方法,如 execute()。命令对象可能会携带执行操作所需的参数。

Concrete Command(具体命令):

该角色实现了命令接口,对具体的操作进行了实现。具体命令对象将一个接收者对象绑定到一个动作,并负责调用接收者的相应方法来执行请求。

Receiver(接收者):

该角色实际执行操作的对象。命令对象会将请求委托给接收者来执行实际的操作。

Invoker/Client(调用者/客户端):

该角色创建命令对象并将其发送给接收者。调用者不需要了解命令是如何执行的,它只需要发送请求。

        整个命令模式的结构图:

二、命令模式

        比如在餐馆就餐,我们会先向服务员点单,下单后服务员通知后厨进行制作,这种就可以用命令模式进行演示。Receiver可以当做是具体制作食物的厨师,Invoker可以当做是服务员进行调用,Command理解成每一个菜单,也就是发出的命令。

        先创建厨师Receiver类:

public class Receiver {

    public void actionOne(){
        System.out.println("制作食物one");
    }

    public void actionTwo(){
        System.out.println("制作食物two");
    }

    public void actionThree(){
        System.out.println("制作食物three");
    }
}

        创建抽象命令Command:

public interface Command {
    void execute();
}

        创建菜单具体的命令:

public class ConcreteCommandOne implements Command{

    private Receiver receiver;

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

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


public class ConcreteCommandTwo  implements Command{
    private Receiver receiver;

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

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

public class ConcreteCommandThree  implements Command{
    private Receiver receiver;

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

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

        创建服务员Invoker类:

public class Invoker {

    private List<Command> commands = new ArrayList<>();

   public void setCommand(Command command){
       commands.add(command);
   }

   public void removeCommand(Command command){
       commands.remove(command);
       System.err.println("取消订单");
   }

    public void call(){
       for (Command command : commands){
           command.execute();

       }
    }
}

        客户端调用类:

public class Client {

    public static void main(String[] args) {
        Receiver receiver = new Receiver();

        Command commandOne = new ConcreteCommandOne(receiver);
        Command commandTwo = new ConcreteCommandTwo(receiver);
        Command commandThree = new ConcreteCommandThree(receiver);

        Invoker invoker = new Invoker();

        invoker.setCommand(commandOne);
        invoker.setCommand(commandTwo);
        invoker.setCommand(commandThree);

        invoker.removeCommand(commandTwo);

        invoker.call();


    }
}

        执行结果:

        可以看出client创建不同的命令,通过invoker将命令设置进去,也可以通过invoker取消命令,最后invoker通知进行调用。

三、总结

        优点与缺点:

优点:

解耦请求发送者和接收者:

命名模式将请求封装成一个对象,使得发送者和接收者之间的解耦程度增加。发送者只需要知道如何发送命令,而不需要了解命令是如何被执行的。

支持撤销和重做操作:

由于命令对象封装了对接收者的调用,因此可以轻松地实现撤销和重做操作,只需保留历史命令对象即可。

增加新的命令:

通过添加新的命令类,可以轻松地扩展命令模式,而无需修改现有的客户端代码。

支持组合命令:

可以通过组合多个命令对象来执行复杂的操作,从而实现更高级的功能。

缺点:

类爆炸:

在系统中可能会产生大量的具体命令类,如果命令种类过多,可能会导致类爆炸,增加系统的复杂性。

增加调试难度:

由于命令模式涉及多个对象之间的交互,因此调试可能会变得更加复杂。

        应用场景:

GUI应用程序:

命令模式常用于实现菜单和工具栏按钮的操作。每个菜单项或按钮可以表示一个命令,当用户点击时,该命令将被执行。

任务队列:

命令模式可以用于实现任务队列,例如,在操作系统中,可以将用户的操作封装成命令对象,然后将它们放入队列中以便逐个执行。

日志系统:

命令模式可以用于实现日志系统,将所有操作封装成命令对象,并在执行时记录相关的日志信息。

撤销/重做功能:

命令模式很适合实现撤销和重做功能,因为每个命令对象都可以保存执行时的状态,从而支持撤销和重做操作。

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

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

相关文章

【C++】C++入门2.0

各位读者老爷好&#xff0c;本鼠最近浅学了一点C的入门知识&#xff01;利用本博客作为笔记的同时也希望得到各位大佬的垂阅&#xff01; 目录 1. 引用 1.1.引用的概念 1.2.引用的特性 1.3.引用的使用场景 1.4.引用的易错点 1.5.引用的优势 1.6.引用和指针 2.内联函数 …

B端UI设计,演绎高情逸态之妙

B端UI设计&#xff0c;演绎高情逸态之妙

汽车IVI中控开发入门及进阶(二十三):i.MX8

前言: IVI市场的复杂性急剧增加,而TimeToMarket在几代产品中从5年减少到2-3年。Tier1正在接近开放系统的模型(用户可以安装应用程序),从专有/关闭源代码到标准接口/开放源代码,从软件堆栈对系统体系结构/应用层/系统验证和鉴定的完全所有权,越来越依赖第三方中间件和平…

STM32自己从零开始实操03:输出部分原理图

一、继电器电路 1.1指路 延续使用 JZC-33F-012-ZS3 继电器&#xff0c;设计出以小电流撬动大电流的继电器电路。 &#xff08;提示&#xff09;电路需要包含&#xff1a;三极管开关电路、续流二极管、滤波电容、指示灯、输出部分。 1.2数据手册重要信息提炼 联系排列&…

Rainbond 携手 TOPIAM 打造企业级云原生身份管控新体验

TOPIAM 企业数字身份管控平台&#xff0c; 是一个开源的IDaas/IAM平台、用于管理账号、权限、身份认证、应用访问&#xff0c;帮助整合部署在本地或云端的内部办公系统、业务系统及三方 SaaS 系统的所有身份&#xff0c;实现一个账号打通所有应用的服务。 传统企业 IT 采用烟囱…

NSS题目练习5

[NISACTF 2022]babyupload 打开后尝试上传php&#xff0c;jpg&#xff0c;png文件都没成功 查看源代码发现有个/source文件 访问后下载压缩包发现有一个python文件 搜索后知道大致意思是&#xff0c;上传的文件不能有后缀名&#xff0c;上传后生成一个uuid&#xff0c;并将uuid…

redis缓存token设置jwt令牌过期时间

登录接口 在上文中 我们已经设置了自定义登录接口自定义拦截器jwt登录校验接口模拟账号登录_jwt自定义拦截器-CSDN博客https://blog.csdn.net/2202_75352238/article/details/138424691?spm1001.2014.3001.5501 但是上文jwt过期时间是由yml文件中配置的&#xff0c;比较不优雅…

Amis源码构建 sdk版本

建议在linux环境下构建&#xff08;mac环境下也可以&#xff09;&#xff0c;需要用到sh脚本&#xff08;amis/build.sh&#xff09;。 Js sdk打包是基于fis进行编译打包的&#xff0c;具体可见fis-conf.js&#xff1a; amis-master源码下载:https://github.com/baidu/amis g…

【OceanBase诊断调优】—— obdiag 工具助力OceanBase数据库诊断调优(DBA 从入门到实践第八期)

1. 前言 昨天给大家分享了【DBA从入门到实践】第八期&#xff1a;OceanBase数据库诊断调优、认证体系和用户实践 中obdiag的部分&#xff0c;今天将其中的内容以博客的形式给大家展开一下&#xff0c;方便大家阅读。 2. 正文 在介绍敏捷诊断工具之前&#xff0c;先说说OceanBa…

【C语言】常见的动态内存的错误

前言 在动态内存函数的使用过程中我们可能会遇到一些错误&#xff0c;这里将常见的错误进行总结。 对NULL解引用 请看以下代码&#xff1a; 可以看到&#xff0c;这时我们的malloc开辟是失败的&#xff0c;所以返回的是空指针NULL&#xff0c;而我们却没有进行检查&#xff0…

使用PNP管控制MCU是否需要复位

这两台用到一款芯片带电池&#xff0c;希望电池还有电芯片在工作的时候插入电源不要给芯片复位&#xff0c;当电池没电&#xff0c;芯片不在工作的时候&#xff0c;插入电源给芯片复位所以使用一个PNP三极管&#xff0c;通过芯片IO控制是否打开复位&#xff0c;当芯片正常工作的…

反激电源压敏电阻设计

压敏电阻的作用&#xff1a;浪涌防护。在电源出现浪涌冲击时&#xff0c;保护核心器件不受到损坏。其实类似于稳压二极管 瞬间的瞬态波 1 压敏电压 单位是&#xff0c;虽然压敏电阻可以吸收很大的浪涌能量&#xff0c;但是不能承受mA以上的持续电流。压敏电压计算公式 2 通流容…

(函数)字符串拼接(C语言)

一、运行结果&#xff1b; 二、源代码&#xff1b; # define _CRT_SECURE_NO_WARNINGS # include <stdio.h> # include <string.h>//声明字符串拼接函数&#xff1b; void splice(char a[100], char b[100]);int main() {//初始化变量值&#xff1b;char a[100] …

unity打包的WebGL部署到IIS问题

部署之后会出错&#xff0c;我遇到的有以下几种&#xff1b; 进度条卡住不动 明明已经部署到了IIS上&#xff0c;为什么浏览网页的时候还是过不去或者直接报错。 进度条卡住不动的问题其实就是wasm和data的错误。 此时在浏览器上按F12进入开发者模式查看错误&#xff08;下图…

【前端】Vuex笔记(超详细!!)

最近花了两周时间&#xff0c;完完全全的跟着Vuex官方的视频学完了Vuex并且详详细细的做了笔记&#xff0c;其中总结部分是我对于整个视频课程的总结&#xff0c;视频部分是跟着视频做的笔记&#xff0c;如果总结部分有不懂的话&#xff0c;直接去视频部分查找对应的笔记即可&a…

uniapp的tooltip功能放到表单laber

在uniapp中&#xff0c;tooltip功能通常是通过view组件的hover-class属性来实现的&#xff0c;而不是直接放在form的label上。hover-class属性可以定义当元素处于hover状态时的样式类&#xff0c;通过这个属性&#xff0c;可以实现一个类似tooltip的效果。 以下是一个简单的例…

9.Halcon3D点云力矩求解-平面拟合用法

1.实现效果 我们在使用3d相机对产品进行扫描生成点云的时候,由于安装问题,所以我们不可能保证每次产品扫描出来都在坐标系中位置和姿态非常标准。 上述算法描述的就是在某一个维度或者某几个维度上将点云数据和坐标系对齐; 至于怎么对齐,如何实现就是今天的内容。 本人能…

热电子光探测器的电磁场空间分布与FDTD材料折射率的导出

仿真实例 金属薄膜中金纳米孔阵列透射与反射&#xff0c; 并考虑其近场电磁分布 利用脚本进行电磁场及其光学响应的可视化 设置EOT型超表面结构&#xff0c;以及Structure library的使用 结构的参数化扫描与结果可视化 利用脚本计算峰值增强因子 多层平面结构激发T…

如何打造智能客服机器人的“超级大脑”?

一、引言 在数字化浪潮的推动下,智能客服机器人已成为企业服务升级、提升客户满意度的关键工具。然而,要让智能客服机器人真正发挥其在客户服务中的优势,打造其“超级大脑”至关重要。本文将深入探讨如何进一步提升智能客服机器人的智能水平,并结合其在多业务场景中面临的挑…

去掉el-table表头右侧类名是gutter,width=17px的空白区域(包括表头样式及表格奇偶行样式和表格自动滚动)

代码如下&#xff1a; <el-table:data"tableData"ref"scroll_Table":header-cell-style"getRowClass":cell-style"styleBack"height"350px"style"width: 100%"><el-table-column prop"id" l…