详解设计模式:命令模式

news2024/9/20 14:30:20

命令模式(Command Pattern)也被称为行动模式(Action Pattern)、事物模式(Transaction Pattern),是在 GoF 23 种设计模式中定义了的行为型模式。

命令模式 是一种数据驱动的设计模式。请求以命令的形式包裹在对象中,并传给调用对象。调用对象寻找可以处理该命令的合适的对象,并把该命令传给相应的对象,该对象执行命令。命令是对命令的封装,每一个命令都是一个操作,请求方发出请求,接收方接收请求,并执行操作。命令模式解耦了请求方和接收方。

本篇文章内容包括:关于命令模式、命令模式 Demo


文章目录

    • 一、关于命令模式
        • 1、关于命令模式
        • 2、关于命令模式的构成
        • 3、关于命令模式的XML
        • 4、关于命令模式的使用场景
        • 5、关于命令模式的优缺点
    • 二、命令模式 Demo
        • 1、Demo 设计
        • 2、Demo 实现
        • 3、Demo 测试


一、关于命令模式

1、关于命令模式

命令模式(Command Pattern)也被称为行动模式(Action Pattern)、事物模式(Transaction Pattern),是在 GoF 23 种设计模式中定义了的行为型模式。

命令模式 是一种数据驱动的设计模式。请求以命令的形式包裹在对象中,并传给调用对象。调用对象寻找可以处理该命令的合适的对象,并把该命令传给相应的对象,该对象执行命令。命令是对命令的封装,每一个命令都是一个操作,请求方发出请求,接收方接收请求,并执行操作。命令模式解耦了请求方和接收方。

2、关于命令模式的构成

命令模式主要包含以下 4 种角色:

  • 命令(Command)角色:定义命令的接口,声明执行的方法。
  • 具体命令(Concrete Command)角色:实现命令接口,是“虚”的实现;通常会持有接收者,并调用接收者的功能来完成命令要执行的操作。
  • 接收者(Receiver)角色:负责具体实施和执行一个请求。任何类都可能成为一个接收者,只要它能够实现命令要求实现的相应功能。
  • 请求者(调用者)角色(Invoker):负责调用命令对象执行请求。

3、关于命令模式的XML

image-20221203225114649

4、关于命令模式的使用场景

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

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

5、关于命令模式的优缺点

# 关于命令模式优点

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

# 关于命令模式缺点

  • 使用命令模式可能会导致某些系统有过多的具体命令类。
  • 系统结构更加复杂。

二、命令模式 Demo

1、Demo 设计

我们使用遥控操作电视,电视操作包括,打开、关闭以及换台

2、Demo 实现

# Command 命令(Command)角色

public interface Command {
    
    /**
     * 操作命令
     */
    void execute();
}

# ConcreteCommand 具体命令(Concrete Command)角色

public class OpenCommand implements Command{

    private final TV tv = new TV();

    /**
     * 打开电视机
     */
    @Override
    public void execute() {
        tv.open();
    }
}
public class ChangeCommand implements Command{

    private final TV tv = new TV();

    /**
     * 换台
     */
    @Override
    public void execute() {
        tv.change();
    }
}
public class CloseCommand implements Command{

    private final TV tv = new TV();

    /**
     * 关闭电视机
     */
    @Override
    public void execute() {
        tv.close();
    }
}

# Control 请求者(调用者)角色(Invoker)

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

public class Control {

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

    public Control(Command command) {
        commands.add(command);
    }

    public Control(List<Command> commands) {
        this.commands.addAll(commands);
    }

    public void action() {
        commands.forEach(Command::execute);
    }
}

# TV 接收者(Receiver)角色

public class TV {

    public void open() {
        System.out.println("打开电视机");
    }

    public void change() {
        System.out.println("切换电视机");
    }

    public void close() {
        System.out.println("关闭电视机");
    }
}

3、Demo 测试

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

public class Client {
    
    public static void main(String[] args) {
        Command command = new OpenCommand();
        Command changeCommand = new ChangeCommand();
        Command closeCommand = new CloseCommand();
        List<Command> list = new ArrayList<>();
        list.add(command);
        list.add(changeCommand);
        list.add(closeCommand);
        Control control = new Control(list);
        control.action();
    }
}

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

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

相关文章

序列类型(元组()、列表[]、字符串““)、集合类型({}、set())

序列类型 组合数据类型能够将多个同类型或不同类型的数据组织起来 &#xff0c;通过单一的表示使数据操作更有序更容易。根据数据之间的 关系&#xff0c;组合数据类型可以分为三类&#xff1a; 序列类型、集合类型和映射类型。 • 序列类型是一个元素向量&#xff0c;元素之间…

Centos8安装CDH解决不兼容问题

问题 我的配置 系统&#xff1a; centos8 安装包&#xff1a; CDH-5.16.1-1.cdh5.16.1.p0.3-el7.parcel CDH-5.16.1-1.cdh5.16.1.p0.3-el7.parcel.sha cloudera-manager-centos7-cm5.16.1_x86_64.tar.gz manifest.json 在 http://192.168.1.1:7180/ 上通过web分配percel时分配…

Python实现基于内容的协同过滤推荐算法构建电影推荐系统

说明&#xff1a;这是一个机器学习实战项目&#xff08;附带数据代码文档视频讲解&#xff09;&#xff0c;如需数据代码文档视频讲解可以直接到文章最后获取。 1.项目背景 基于内容(Content Based,CB)的推荐算法&#xff0c;根据用户过去是一段时间内喜欢的物品&#xff0c;由…

DHTMLX Spreadsheet JavaScript Pro 5.0

Spreadsheet — Web-Based Spreadsheet Solution 破解版DHTMLX Spreadsheet is a framework-agnostic JavaScript solution that allows you to quickly add an editable Excel-like spreadsheet on a web page. Unlike online services, DHTMLX Spreadsheet allows you to st…

Windows x64隐藏可执行内存

文章目录实现效果实现原理VAD内存什么是VAD内存查看VAD内存VAD属性VAD内存可利用的点x64分页机制W7 x64下任意地址PDT PTE算法W10 x64定位随机化页表基址实现隐藏可执行内存隐藏内存对抗实现效果 驱动程序在Test进程中申请一块内存地址并打印&#xff0c;然后控制台程序在接收到…

Web中的Bias(更新中)

目录前言数据偏见对人们的影响衡量偏见活跃偏差或少数人的智慧数据偏见其他参考文献前言 本文参考Ricardo Baeza-Yates 2018年发表在《Communications of the ACM》的论文Bias on the Web&#xff0c;论文旨在提高人们对网络使用和内容中存在的偏见对我们所有人造成的潜在影响…

Methyltetrazine-PEG4-NHS ester,甲基四嗪PEG4琥珀酰亚胺酯

一&#xff1a;产品描述 1、名称 英文&#xff1a;Methyltetrazine-PEG4-NHS ester 中文&#xff1a;甲基四嗪-四聚乙二醇-琥珀酰亚胺酯 2、CAS编号&#xff1a;1802907-92-1 3、所属分类&#xff1a;Tetrazine 4、分子量&#xff1a;533.54 5、分子式&#xff1a;C24H3…

qt单线程实现顺序事件的处理不卡顿技巧(IDE开发)

需求&#xff1a; 我现在是这样的需求&#xff0c;我正在开发一款嵌入式IDE中&#xff0c;编辑器中光标改变&#xff0c;右侧的符号大纲能对应的改变选中项。 这里的过程是这样的&#xff0c;鼠标位置改变事件函数里&#xff0c;通过光标行号&#xff0c;计算得到当前处于的符…

通过私钥连接腾讯云,实现免密远程登录

一、创建 SSH 密钥 系统提示不会保存私钥&#xff0c;要求用户在 10 分钟之内自行下载私钥&#xff0c;要保存在本地电脑和邮箱里面备用。 二、绑定密钥到云服务器 勾选刚才创建的 SSH 密钥&#xff0c;点击上面的绑定云主机&#xff0c;弹窗中要先找到你云主机的地域&#x…

【计算机毕业设计】74.家教平台系统源码

一、系统截图&#xff08;需要演示视频可以私聊&#xff09; 摘 要 21世纪的今天&#xff0c;随着社会的不断发展与进步&#xff0c;人们对于信息科学化的认识&#xff0c;已由低层次向高层次发展&#xff0c;由原来的感性认识向理性认识提高&#xff0c;管理工作的重要性已逐…

CentosLinux 6.5安装教程

、开始安装Centos6.5&#xff1a;我们选择“inistall system with basic video driver” 注意&#xff1a;这是一种精简系统的安装模式&#xff1a; 1.安装或升级现有的系统&#xff1b; 2.安装系统并使用基本的显卡驱动&#xff1b; 3.进入系统修复模式&#xff1b; 4.从硬盘…

[附源码]Python计算机毕业设计SSM竞赛报名管理系统(程序+LW)

项目运行 环境配置&#xff1a; Jdk1.8 Tomcat7.0 Mysql HBuilderX&#xff08;Webstorm也行&#xff09; Eclispe&#xff08;IntelliJ IDEA,Eclispe,MyEclispe,Sts都支持&#xff09;。 项目技术&#xff1a; SSM mybatis Maven Vue 等等组成&#xff0c;B/S模式 M…

【计算机毕业设计】基于jsp网上书店(源代码+论文)

网上书店系统 1.需求分析。 参考设计要求&#xff0c;及可行性的分析&#xff0c;我们确定了如下的需求&#xff1a; 1.数据库设计科学合理。 2.网站主页面简洁美观&#xff0c;可以天蓝色为主色调。 3.网站主页显示各个分类的及总的畅销表、新书榜、推荐榜&#xff0c;显…

Allegro如何锁定器件操作指导

Allegro如何锁定器件操作指导 Allegro上可以锁定器件,避免误操作被移动,具体操作如下 选择fix命令 Find选择Symbols 框选需要锁定的器件 可以看到器件被锁住了 除了这个方法之外,还有另外一种方法锁定器件,选择edit-property Find选择Symbols

ADSP-21569/ADSP-21593的开发入门(中)

ADSP-21569/21593的软件准备 安装CCES软件&#xff0c;我装的是2.10.1&#xff0c;官网可以下载&#xff0c;我也可以提供。软件安装没什么可说的&#xff0c;全部下一步&#xff0c;软件的试用跟注册可以单独联系我。 https://www.analog.com/cn/design-center/evaluation-h…

做短视频创业之前必须确定的内容:变现形式,短视频玩法和人设定位

做短视频创业之前必须确定的内容&#xff1a;变现形式&#xff0c;短视频玩法和人设定位。这是短视频的根基&#xff0c;打好基础才能更好的实现盈利目标。 开始做短视频的时候&#xff0c;走了很多弯路&#xff0c;这段时间总结了之前的经验教训&#xff0c;结合在我赢助手上…

【编程题】【Scratch四级】2022.09 班级成绩处理

班级成绩处理 三年级1班有36个小朋友&#xff0c;某次数学考试&#xff0c;同学们的成绩在78-100之间&#xff0c;求出该班学生的平均分和成绩优秀的人数&#xff08;成绩大于85分&#xff09;。 1. 准备工作 &#xff08;1&#xff09;默认小猫角色&#xff0c;默认白色背景…

Python学习基础笔记二十一——迭代器

列表&#xff0c;我们使用for循环来取值&#xff0c;我们把每个值都取到&#xff0c;不需要关心每一个值的位置&#xff0c;因为只能顺序的取值&#xff0c;并不能跳过任何一个去取其他位置的值。那么我们为什么可以使用for循环来取值&#xff0c;for循环内部是怎么工作的呢&am…

【力扣算法简单五十题】17.路径总和

给你二叉树的根节点 root 和一个表示目标和的整数 targetSum 。判断该树中是否存在 根节点到叶子节点 的路径&#xff0c;这条路径上所有节点值相加等于目标和 targetSum 。如果存在&#xff0c;返回 true &#xff1b;否则&#xff0c;返回 false 。 叶子节点 是指没有子节点…

模仿Spring注入接口的代理类全过程

前言 在使用mybatis或者openFeign时只定义了一个接口类&#xff0c;并无实现类&#xff0c;可以把接口注入到service中并且能调用方法返回值。一个接口并无实现类&#xff0c;为什么可以实例化并且交给了spring管理。mybatis&#xff0c;OpenFeign又是怎么实现的&#xff1f;接…