十七、命令模式

一、什么是命令模式

  命令(Command)模式的定义:将一个请求封装为一个对象,使发出请求的责任和执行请求的责任分割开。这样两者之间通过命令对象进行沟通,这样方便将命令对象进行储存、传递、调用、增加与管理。
  命令模式包含以下主要角色:

  • 抽象命令类(Command)角色:声明执行命令的接口,拥有执行命令的抽象方法 execute()。
  • 具体命令类(Concrete Command)角色:是抽象命令类的具体实现类,它拥有接收者对象,并通过调用接收者的功能来完成命令要执行的操作。
  • 实现者/接收者(Receiver)角色:执行命令功能的相关操作,是具体命令对象业务的真正实现者。
  • 调用者/请求者(Invoker)角色:是请求的发送者,它通常拥有很多的命令对象,并通过访问命令对象来执行相关请求,它不直接访问接收者。

二、命令模式的实现

  • 抽象命令类(Command)
/*** @author FluffyCatkin* @version 1.0* @date 2020/1/7 0007 10:45* @description 抽象命令类(Command)角色:声明执行命令的接口,拥有执行命令的抽象方法 execute()。*/
public interface Command {void execute();
}
  • 调用者/请求者(Invoker)

/*** @author FluffyCatkin* @version 1.0* @date 2020/1/7 0007 10:47* @description 调用者/请求者(Invoker)角色:是请求的发送者,它通常拥有很多的命令对象,并通过访问命令对象来执行相关请求,它不直接访问接收者。*/
public class Invoker {private Command command;public Invoker(Command command) {this.command = command;}public void setCommand(Command command) {this.command = command;}public void call(){command.execute();}
}
  • 实现者/接收者(Receiver)
/*** @author FluffyCatkin* @version 1.0* @date 2020/1/7 0007 10:47* @description 实现者/接收者(Receiver)角色:执行命令功能的相关操作,是具体命令对象业务的真正实现者。*/
public class Receiver {private String name;public Receiver(String name) {this.name = name;}public void action(){System.out.println(name+"命令被执行......................");}
}
  • 具体命令角色(Concrete Command)

/*** @author FluffyCatkin* @version 1.0* @date 2020/1/7 0007 10:46* @description 具体命令角色(Concrete  Command)角色:是抽象命令类的具体实现类,它拥有接收者对象,并通过调用接收者的功能来完成命令要执行的操作。*/
public class ConcreteCommand implements Command {private Receiver receiver;public ConcreteCommand() {this.receiver = new Receiver("receiver.......");}@Overridepublic void execute() {receiver.action();}
}
  • 测试类

/*** @author FluffyCatkin* @version 1.0* @date 2020/1/7 0007 10:42* @description 命令模式** 在软件开发系统中,常常出现“方法的请求者”与“方法的实现者”之间存在紧密的耦合关系。这不利于软件功能的扩展与维护。例如,想对行为进行“撤销、重做、记录”等处理都很不方便,因此“如何将方法的请求者与方法的实现者解耦?”变得很重要,命令模式能很好地解决这个问题。** 在现实生活中,这样的例子也很多,例如,电视机遥控器(命令发送者)通过按钮(具体命令)来遥控电视机(命令接收者),还有计算机键盘上的“功能键”等。* 命令模式的定义与特点:* 命令(Command)模式的定义如下:将一个请求封装为一个对象,使发出请求的责任和执行请求的责任分割开。这样两者之间通过命令对象进行沟通,这样方便将命令对象进行储存、传递、调用、增加与管理。** 命令模式的主要优点如下:* 降低系统的耦合度。命令模式能将调用操作的对象与实现该操作的对象解耦。* 增加或删除命令非常方便。采用命令模式增加与删除命令不会影响其他类,它满足“开闭原则”,对扩展比较灵活。* 可以实现宏命令。命令模式可以与组合模式结合,将多个命令装配成一个组合命令,即宏命令。* 方便实现 Undo 和 Redo 操作。命令模式可以与后面介绍的备忘录模式结合,实现命令的撤销与恢复。** 其缺点是:可能产生大量具体命令类。因为计对每一个具体操作都需要设计一个具体命令类,这将增加系统的复杂性。* 命令模式的结构与实现:* 可以将系统中的相关操作抽象成命令,使调用者与实现者相关分离,其结构如下。* 模式的结构:* 命令模式包含以下主要角色。抽象命令类(Command)角色:声明执行命令的接口,拥有执行命令的抽象方法 execute()。* 具体命令角色(Concrete    Command)角色:是抽象命令类的具体实现类,它拥有接收者对象,并通过调用接收者的功能来完成命令要执行的操作。* 实现者/接收者(Receiver)角色:执行命令功能的相关操作,是具体命令对象业务的真正实现者。* 调用者/请求者(Invoker)角色:是请求的发送者,它通常拥有很多的命令对象,并通过访问命令对象来执行相关请求,它不直接访问接收者。* 命令模式的应用场景:* 命令模式通常适用于以下场景。当系统需要将请求调用者与请求接收者解耦时,命令模式使得调用者和接收者不直接交互。* 当系统需要随机请求命令或经常增加或删除命令时,命令模式比较方便实现这些功能。* 当系统需要执行一组操作时,命令模式可以定义宏命令来实现该功能。* 当系统需要支持命令的撤销(Undo)操作和恢复(Redo)操作时,可以将命令对象存储起来,采用备忘录模式来实现。*/
public class Main {/*** 测试简单的命令模式*/@Testpublic void commandTest(){Command command = new ConcreteCommand();Invoker invoker = new Invoker(command);invoker.call();}
}

运行结果:

receiver.......命令被执行......................Process finished with exit code 0

三、应用场景

  命令模式通常适用于以下场景:

  • 请求调用者需要与请求接收者解耦时,命令模式可以使调用者和接收者不直接交互。
  • 系统随机请求命令或经常增加、删除命令时,命令模式可以方便地实现这些功能。
  • 当系统需要执行一组操作时,命令模式可以定义宏命令来实现该功能。
  • 当系统需要支持命令的撤销(Undo)操作和恢复(Redo)操作时,可以将命令对象存储起来,采用备忘录模式来实现。

四、优缺点分析

  当系统的某项操作具备命令语义,且命令实现不稳定(变化)时,可以通过命令模式解耦请求与实现。使用抽象命令接口使请求方的代码架构稳定,封装接收方具体命令的实现细节。接收方与抽象命令呈现弱耦合(内部方法无需一致),具备良好的扩展性。
  命令模式的主要优点如下

  • 通过引入中间件(抽象接口)降低系统的耦合度。
  • 扩展性良好,增加或删除命令非常方便。采用命令模式增加与删除命令不会影响其他类,且满足“开闭原则”。
  • 可以实现宏命令。命令模式可以与组合模式结合,将多个命令装配成一个组合命令,即宏命令。
  • 方便实现 Undo 和 Redo 操作。命令模式可以与后面介绍的备忘录模式结合,实现命令的撤销与恢复。
  • 可以在现有命令的基础上,增加额外功能。比如日志记录,结合装饰器模式会更加灵活。

  其缺点是

  • 可能产生大量具体的命令类。因为每一个具体操作都需要设计一个具体命令类,这会增加系统的复杂性。
  • 命令模式的结果其实就是接收方的执行结果,但是为了以命令的形式进行架构、解耦请求与实现,引入了额外类型结构(引入了请求方与抽象命令接口),增加了理解上的困难。不过这也是设计模式的通病,抽象必然会额外增加类的数量,代码抽离肯定比代码聚合更加难理解。

代码地址:https://gitee.com/fluffycatkin/JavaDesignModel.git

image.png

原文出处:http://c.biancheng.net/view/1380.html

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

如若内容造成侵权/违法违规/事实不符,请联系编程知识网进行投诉反馈email:809451989@qq.com,一经查实,立即删除!

相关文章

SQL注入漏洞复现(CVE-2017-8917)

文章目录 搭建环境启动环境漏洞复现报错注入使用sqlmap 前提条件: 1.安装docker docker pull medicean/vulapps:j_joomla_22.安装docker-compose docker run -d -p 8000:80 medicean/vulapps:j_joomla_23.下载vulhub Docker Compose是 docker 提供的一个命令行工具&…

学习pytorch7 神经网络的基本骨架--nn,module的使用

神经网络的基本骨架--nn,module的使用 官网Module介绍Python父类子类继承关系前向神经网络pycharm快捷键重写类方法codedebug B站小土堆视频学习笔记 官网Module介绍 https://pytorch.org/docs/stable/generated/torch.nn.Module.html#torch.nn.Module Python父类子类继承关系…

1.8.6 练习 本科生学平均分绩点GPA计算(堆数组的应用)

C自学精简教程 目录(必读) 上大学要考试 我们读大学也要上课,上课也要考试的。 基本上每门课也都是满分100分。 虽然选择一个专业要上很多门课,每门课也都是100分,但是这些课程的“价值”却是不一样的。 有的课程是核心专业课&#xff1…

《游戏编程模式》学习笔记(九)游戏循环 Sequencing Patterns

定义 一个游戏循环会在游玩时不断运行。 每一次循环,它都会无阻塞地处理玩家的输入,更新游戏的状态,渲染游戏。它追踪时间的消耗并控制游戏的速度。游戏循环需要做到始终以固定的速度运行游戏。 一个游戏循环中通常包含处理输入部分&#xf…

设计模式的使用——模板方法模式+动态代理模式

一、需求介绍 现有自己写的的一套审批流程逻辑,由于代码重构,需要把以前的很多业务加上审批的功能,再执行完审批与原有业务之后,生成一个任务,然后再统一处理一个任务(本来是通过数据库作业去处理的&#x…

上海炒股开户哪个证券公司好?找谁能开低佣金的账户?

在上海炒股开户选择哪家券商都可以,但是要拿到低佣金的账户就有点难度了。上海,简称“沪,是国务院批复确定的中国国际经济、金融、贸易、航运、科技创新中心!正是如此,上海地区的券商公司也是非常之多的,这…

论文阅读 FCOS: Fully Convolutional One-Stage Object Detection

文章目录 FCOS: Fully Convolutional One-Stage Object DetectionAbstract1. Introduction2. Related Work3. Our Approach3.1. Fully Convolutional One-Stage Object Detector3.2. Multi-level Prediction with FPN for FCOS3.3. Center-ness for FCOS 4. Experiments4.1. Ab…

【网络设备】交换机的概念、工作原理、功能以及以太网帧格式

个人主页:insist--个人主页​​​​​​ 本文专栏:网络基础——带你走进网络世界 本专栏会持续更新网络基础知识,希望大家多多支持,让我们一起探索这个神奇而广阔的网络世界。 目录 一、认识交换机 二、交换机的主要功能 1、数…

Maven入门教程(一):安装Maven环境

视频教程:Maven保姆级教程 Maven入门教程(一):安装Maven环境 Maven入门教程(二):idea/Eclipse使用Maven Maven入门教程(三):Maven语法 Maven入门教程(四):Nexus私服 Maven入门教程(五):自定义脚手架 Maven项…

二三维电子沙盘数字沙盘虚拟现实开发教程第14课

二三维电子沙盘数字沙盘开发教程第14课 很久没有写了,主要前段时间在针对怎么显示高精度的 倾斜数据而努力,现在终于实现了效果不错。以前的版本显示倾斜数据控制不太好。 对了。目前系统暂只支持smart3d生成的kml格式的数据,由专有的录入程…

AI:05 - 基于深度学习的道路交通信号灯的检测与识别

随着人工智能的快速发展,基于深度学习的视觉算法在道路交通领域中起到了重要作用。本文将探讨如何利用深度学习技术实现道路交通信号灯的检测与识别,通过多处代码实例展示技术深度。 道路交通信号灯是指示交通参与者行驶和停止的重要信号。准确地检测和识别交通信号灯对于智…

C语言每日一练------(Day3)

本专栏为c语言练习专栏,适合刚刚学完c语言的初学者。本专栏每天会不定时更新,通过每天练习,进一步对c语言的重难点知识进行更深入的学习。 今天练习题的关键字: 尼科彻斯定理 等差数列 💓博主csdn个人主页&#xff1a…