详解设计模式:命令模式
创始人
2024-03-17 07:39:34
0

命令模式(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();/*** 打开电视机*/@Overridepublic void execute() {tv.open();}
}
public class ChangeCommand implements Command{private final TV tv = new TV();/*** 换台*/@Overridepublic void execute() {tv.change();}
}
public class CloseCommand implements Command{private final TV tv = new TV();/*** 关闭电视机*/@Overridepublic void execute() {tv.close();}
}

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

import java.util.ArrayList;
import java.util.List;public class Control {public List commands = new ArrayList<>();public Control(Command command) {commands.add(command);}public Control(List 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 list = new ArrayList<>();list.add(command);list.add(changeCommand);list.add(closeCommand);Control control = new Control(list);control.action();}
}

相关内容

热门资讯

监控摄像头接入GB28181平... 流程简介将监控摄像头的视频在网站和APP中直播,要解决的几个问题是:1&...
Windows10添加群晖磁盘... 在使用群晖NAS时,我们需要通过本地映射的方式把NAS映射成本地的一块磁盘使用。 通过...
protocol buffer... 目录 目录 什么是protocol buffer 1.protobuf 1.1安装  1.2使用...
在Word、WPS中插入AxM... 引言 我最近需要写一些文章,在排版时发现AxMath插入的公式竟然会导致行间距异常&#...
Fluent中创建监测点 1 概述某些仿真问题,需要创建监测点,用于获取空间定点的数据࿰...
educoder数据结构与算法...                                                   ...
MySQL下载和安装(Wind... 前言:刚换了一台电脑,里面所有东西都需要重新配置,习惯了所...
MFC文件操作  MFC提供了一个文件操作的基类CFile,这个类提供了一个没有缓存的二进制格式的磁盘...
有效的括号 一、题目 给定一个只包括 '(',')','{','}'...
【Ctfer训练计划】——(三... 作者名:Demo不是emo  主页面链接:主页传送门 创作初心ÿ...