【设计模式】第二十一章:命令模式详解及应用案例

news2024/11/25 18:26:40

系列文章

【设计模式】七大设计原则
【设计模式】第一章:单例模式
【设计模式】第二章:工厂模式
【设计模式】第三章:建造者模式
【设计模式】第四章:原型模式
【设计模式】第五章:适配器模式
【设计模式】第六章:装饰器模式
【设计模式】第七章:代理模式
【设计模式】第八章:桥接模式
【设计模式】第九章:外观模式 / 门面模式
【设计模式】第十章:组合模式
【设计模式】第十一章:享元模式
【设计模式】第十二章:观察者模式
【设计模式】第十三章:模板方法模式
【设计模式】第十四章:策略模式
【设计模式】第十五章:责任链模式
【设计模式】第十六章:迭代器模式
【设计模式】第十七章:状态模式
【设计模式】第十八章:备忘录模式
【设计模式】第十九章:访问者模式
【设计模式】第二十章:解释器模式
【设计模式】第二十一章:命令模式
【设计模式】第二十二章:中介者模式


文章目录

  • 系列文章
  • 命令模式
  • 一、定义
  • 二、角色分类
  • 三、实现方式
    • UML图
    • 具体实现
  • 四、应用场景
  • 五、优缺点
    • 优点
    • 缺点


命令模式

一、定义

摘自百度百科: 在软件系统中,“行为请求者”与“行为实现者”通常呈现一种“紧耦合”。但在某些场合,比如要对行为进行“记录、撤销/重做、事务”等处理,这种无法抵御变化的紧耦合是不合适的。在这种情况下,如何将“行为请求者”与“行为实现者”解耦?将一组行为抽象为对象实现二者之间的松耦合。这就是命令模式(Command Pattern)。


二、角色分类

抽象命令者(Command)

通常情况下为接口或抽象类,用于定义命令的接口,声明要执行的方法

具体命令者(Concrete Command)

其为命令者的子类,通常会有一个接收者,并调用接收者的方法来完成命令要执行的操作

抽象接收者/抽象实现者(Receiver)

真正要执行命令的对象

具体接收者/具体实现者(Concrete Receiver)

其类为抽象接收者的类,实现了在抽象接收者中定义的方法

调用者/请求者(Invoker)

要求命令对象执行请求,通常会持有命令对象,可以有很多的命令对象。这个类是客户端真正触发并要求命令执行相应操作的地方,相当于命令对象的入口

客户角色(Client)

具体调用方法的地方


三、实现方式

UML图

在这里插入图片描述

具体实现

我们可以使用一个简单的示例来深入的说明一下命令模式

抽象命令者(Command)

public abstract class Command {
  public abstract void execute();
}

调用者(Invoker)

public class Invoker {
  private Command command;

  public void Invoker(Command command) {
    this.command = command;
  }

  public void setCommand(Command command) {
    this.command = command;
  }

  public void call() {
    command.execute();
  }
}

具体命令者(Concrete Command)

public class ConcreteCommand extends Command {
  private Receiver receiver;

  public ConcreteCommand(Receiver receiver) {
    super();
    this.receiver = receiver;
  }

  public void execute() {
    receiver.action();
  }
}

抽象接收者(Receiver)

public abstract class Receiver {
  public abstract void action();
}

具体接收者(Concrete Receiver)

public class ConcreteReceiverA extends Receiver {

  @Override
  public void action() {
    System.out.println("接收者A收到命令");
  }
}

public class ConcreteReceiverB extends Receiver {

  @Override
  public void action() {
    System.out.println("接收者B收到命令");
  }
}

客户角色(Client)

public class Client {
  public static void main(String[] args) {
    Receiver receiverA = new ConcreteReceiverA();
    Command command1 = new ConcreteCommand(receiverA);

    Invoker invoker = new Invoker();
    invoker.setCommand(command1);
    invoker.call();

    Receiver receiverB = new ConcreteReceiverB();
    Command command2 = new ConcreteCommand(receiverB);

    invoker.setCommand(command2);
    invoker.call();
  }
}

运行结果

接收者A收到命令
接收者B收到命令

四、应用场景

以下部分内容摘自菜鸟教程

意图: 将一个请求封装成一个对象,从而使您可以用不同的请求对客户进行参数化。

主要解决: 在软件系统中,行为请求者与行为实现者通常是一种紧耦合的关系,但某些场合,比如需要对行为进行记录、撤销或重做、事务等处理时,这种无法抵御变化的紧耦合的设计就不太合适。

何时使用: 在某些场合,比如要对行为进行"记录、撤销/重做、事务"等处理,这种无法抵御变化的紧耦合是不合适的。在这种情况下,如何将"行为请求者"与"行为实现者"解耦?将一组行为抽象为对象,可以实现二者之间的松耦合。

如何解决: 通过调用者调用接受者执行命令,顺序:调用者→命令→接受者。

关键代码:

定义三个角色:

  1. received 真正的命令执行对象
  2. Command
  3. invoker 使用命令对象的入口

应用实例: struts 1 中的 action 核心控制器 ActionServlet 只有一个,相当于 Invoker,而模型层的类会随着不同的应用有不同的模型类,相当于具体的 Command。

使用场景: 认为是命令的地方都可以使用命令模式,比如:

  1. GUI 中每一个按钮都是一条命令。
  2. 模拟 CMD。

注意事项: 系统需要支持命令的撤销(Undo)操作和恢复(Redo)操作,也可以考虑使用命令模式,见命令模式的扩展。


五、优缺点

优点

  1. 降低了系统耦合度。
  2. 新的命令可以很容易添加到系统中去。

缺点

使用命令模式可能会导致某些系统有过多的具体命令类。

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

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

相关文章

shiro系列vulhub所有漏洞复现CVE-2020-1957、CVE-2016-4437、CVE-2010-3863、shiro-721 代码执行

文章目录 Apache Shiro 认证绕过漏洞(CVE-2020-1957)漏洞详情:复现: Apache Shiro 1.2.4反序列化漏洞(CVE-2016-4437)漏洞详情:复现: Apache Shiro 认证绕过漏洞(CVE-2010-3863&…

实验二(OSPF+PPP+hub-spoke)7 5

1.合理划分IP地址: R1: R2: R3: R4: R5: R6: 2.启用OSPF单区域: R1及路由表: [r1]display ip routing-table protocol ospf R2及路由表: R3及路由表&#…

Atlassian Jira Software 9.9.1 特别版

敏捷团队首选的软件开发工具,Atlassian Jira Software 专为软件团队中的每位成员构建,可用于规划、跟踪和发布卓越的软件。 Scrum 板 利用可自定义的 Scrum 板,敏捷团队可集中精力尽可能迅速地交付迭代和增量价值。 看板 借助灵活的看板图&am…

【MySQL】在Linux下删除和安装MySQL

文章目录 一、前言二、检查、卸载内置环境三、获取mysql官方yum源四、正式安装MySQL服务五、登录MySQL配置my.cnf设置开机启动 一、前言 大家好久不见,今天开始分享关系型数据库Mysql的一些知识。 二、检查、卸载内置环境 2.1 首先使用命令查询当前mysql的运行状…

解决dbeaver查询结果乱码问题

问题描述: 通过dbeaver查询informinx 查询结果数据集是乱码 解决方案 : 右键编辑连接 在驱动属性里面新增 用户属性 NEWCODESET 值为 GBK,8859-1,819 解决数据库本身就是GBK编码,但是查询结果集编码不一致难题

Python+CNN 手写公式识别计算系统

系统:Win10 环境:Pycharm/Vscode Python3.7 效果图: 部分代码如下: import torch import torch.nn as nn import torch.nn.functional as F import torch.optim as optim from torchvision import datasets,transforms#定义…

5.8.9 TCP拥塞控制

5.8.9 TCP拥塞控制 我们先来说一个生活中的例子,在节假日到来的时候,由于高速公路免费通行,大量汽车涌上高速公路,最终造成交通拥堵,类似的情况也有可能出现在网络中,由于核心的交换设备在存储、带宽、速率…

ReentrantReadWriteLock读写锁

1、锁的分类 2、读写锁 读锁&#xff1a;共享锁 写锁&#xff1a;独占锁 3、代码01 class MyCache{private volatile Map<String,Object> map new HashMap<>();private ReadWriteLock rwLock new ReentrantReadWriteLock();public void put(String key,Obje…

Windows 如何打开和编辑.lnk文件

文章目录 一、背景二、查看/修改.lnk文件内容方案1&#xff1a;用type命令查看方案2&#xff1a;更改.lnk文件后缀为.txt再查看方案3&#xff1a;用记事本或NodePad打开方案4&#xff1a;使用HxD hex editor十六进制编辑器方案5&#xff1a;使用第三方库查看或编辑1. Matmaus/L…

GO语言中Protocol buffer简介

Protocol buffer 一、Protobuf简介 1.1、RPC 通信 对于单独部署&#xff0c;独立运行的微服务实例而言&#xff0c;在业务需要时&#xff0c;需要与其他服务进行通信&#xff0c;这种通信方式是进程之间的通讯方式&#xff08;inter-process communication&#xff0c;简称I…

机器学习 day23(激活函数的作用,线性激活函数的不足)

线性激活函数的局限性 如果我们将神经网络模型中的所有激活函数都设为线性激活函数&#xff0c;那整个神经网络模型就跟线性回归模型极其相似&#xff0c;且它无法拟合比线性回归模型更复杂的关系 激活函数全设为线性回归激活函数的例子 若把a带入a&#xff0c;则a可简化为…

Unity包体积优化实践

目录 简述优化前优化中assets目录资源ab包动态下发资源大小优化dll大小优化场景模型动态下载和加载优化assets目录后大小 lib目录优化目标架构裁剪代码优化代码和引用 其他优化项Shader优化Release模式编译选项 优化后 简述 在移动端App混合Unity开发的项目中&#xff0c;Unit…

VSCode配置C/C++环境(极简版)

预期结果&#xff1a; 首先安装扩展&#xff1a; 然后按照下面readme.txt中即可 链接&#xff1a;https://pan.baidu.com/s/16OV5Kr82i0gWCc4bvKs42g 提取码&#xff1a;zxcv

【模式识别目标检测】——模式识别技术车牌检测应用

目录 引入 一、模式识别主要方法 1、统计模式识别 2、基于隐马尔可夫模型识别 3、模糊模式识别 4、人工神经网络模式识别 总结 二、模式识别应用 1、车牌定位 2、车牌识别 参考文献&#xff1a; 引入 人在观察事物或现象时&#xff0c;常寻找它与其他事物或现象不同…

江苏某农商行稳健发展,软件安全推动金融服务新气象

​江苏某农商银行是全国最早成立的农商行之一。面对复杂严峻的内外部形势&#xff0c;该农商行在坚守服务“三农”与小微市场的同时&#xff0c;紧跟改革脚步&#xff0c;不断探索业务创新与数字化转型&#xff0c;实现经营稳健发展。 打造多维度数字化体系 驱动农商行创新发展…

QT之一种notifiation使用

简介 使用Qt5实现的消息提醒功能。 本文借助消息通知开源框架实现消息通知功能&#xff0c;软件包在上面。 使用说明 在pro工程中包含qtnotify2.pri 使用举例 include($$PWD/../src/qtnotify2.pri)// 包含头文件 #include "notifymanager.h"// 可建立全局实例 N…

深入理解MySQL数据库存储引擎及数据授权

深入理解MySQL数据库存储引擎及数据授权 一、MySQL数据库存储引擎的概述1.InnoDB引擎2.MyISAM引擎3.Memory引擎 二、MySQL数据授权问题1.用户管理2.数据库级授权3.表级授权4.列级授权5.收回权限 引言&#xff1a; MySQL是一款广泛应用的关系型数据库管理系统&#xff0c;为了满…

Linux常用命令——exportfs命令

在线Linux命令查询工具 exportfs 管理NFS共享文件系统列表 补充说明 exportfs 命令用来管理当前NFS共享的文件系统列表。 参数&#xff1a; -a 打开或取消所有目录共享。 -o options,...指定一列共享选项&#xff0c;与 exports(5) 中讲到的类似。 -i 忽略 /etc/exports 文…

IMX6ULL 移植篇-uboot网络命令NFS下载的文件的验证

一. 简介 本文承接以下文章&#xff1a; IMX6ULL 移植篇-uboot 网络命令NFS_凌肖战的博客-CSDN博客 之前学习了&#xff0c;如何通过NFS服务&#xff0c;向开发板下载 zImage文件&#xff08;内核镜像文件&#xff09;。 本文主要学习对 下载到开发板的 zImage文件内容进行验…

基于深度学习的高精度刀具检测识别系统(PyTorch+Pyside6+YOLOv5模型)

摘要&#xff1a;基于深度学习的高精度刀具检测识别系统可用于日常生活中或野外来检测与定位刀具目标&#xff0c;利用深度学习算法可实现图片、视频、摄像头等方式的刀具目标检测识别&#xff0c;另外支持结果可视化与图片或视频检测结果的导出。本系统采用YOLOv5目标检测模型…