《JAVA与模式》之命令模式

news2024/11/25 12:34:33

系列文章目录


文章目录

  • 系列文章目录
  • 前言
  • 一、命令模式的结构
  • 二、AudioPlayer系统
  • 三、宏命令
  • 四、命令模式的优点


前言

前些天发现了一个巨牛的人工智能学习网站,通俗易懂,风趣幽默,忍不住分享一下给大家。点击跳转到网站,这篇文章男女通用,看懂了就去分享给你的码吧。
在这里插入图片描述
在阎宏博士的《JAVA与模式》一书中开头是这样描述命令(Command)模式的:

命令模式属于对象的行为模式。命令模式又称为行动(Action)模式或交易(Transaction)模式。

命令模式把一个请求或者操作封装到一个对象中。命令模式允许系统使用不同的请求把客户端参数化,对请求排队或者记录请求日志,可以提供命令的撤销和恢复功能。


一、命令模式的结构

命令模式是对命令的封装。命令模式把发出命令的责任和执行命令的责任分割开,委派给不同的对象。

每一个命令都是一个操作:请求的一方发出请求要求执行一个操作;接收的一方收到请求,并执行操作。命令模式允许请求的一方和接收的一方独立开来,使得请求的一方不必知道接收请求的一方的接口,更不必知道请求是怎么被接收,以及操作是否被执行、何时被执行,以及是怎么被执行的。

命令允许请求的一方和接收请求的一方能够独立演化,从而具有以下的优点:

(1)命令模式使新的命令很容易地被加入到系统里。

(2)允许接收请求的一方决定是否要否决请求。

(3)能较容易地设计一个命令队列。

(4)可以容易地实现对请求的撤销和恢复。

(5)在需要的情况下,可以较容易地将命令记入日志。

下面以一个示意性的系统,说明命令模式的结构。
在这里插入图片描述
命令模式涉及到五个角色,它们分别是:

●  客户端(Client)角色:创建一个具体命令(ConcreteCommand)对象并确定其接收者。

●  命令(Command)角色:声明了一个给所有具体命令类的抽象接口。

●  具体命令(ConcreteCommand)角色:定义一个接收者和行为之间的弱耦合;实现execute()方法,负责调用接收者的相应操作。execute()方法通常叫做执行方法。

●  请求者(Invoker)角色:负责调用命令对象执行请求,相关的方法叫做行动方法。

●  接收者(Receiver)角色:负责具体实施和执行一个请求。任何一个类都可以成为接收者,实施和执行请求的方法叫做行动方法。

源代码
  接收者角色类

复制代码
public class Receiver {
/**
* 真正执行命令相应的操作
*/
public void action(){
System.out.println(“执行操作”);
}
}
复制代码
  抽象命令角色类

复制代码
public interface Command {
/**
* 执行方法
*/
void execute();
}
复制代码
  具体命令角色类

复制代码
public class ConcreteCommand implements Command {
//持有相应的接收者对象
private Receiver receiver = null;
/**
* 构造方法
*/
public ConcreteCommand(Receiver receiver){
this.receiver = receiver;
}
@Override
public void execute() {
//通常会转调接收者对象的相应方法,让接收者来真正执行功能
receiver.action();
}

}
复制代码
  请求者角色类

复制代码
public class Invoker {
/**
* 持有命令对象
/
private Command command = null;
/
*
* 构造方法
/
public Invoker(Command command){
this.command = command;
}
/
*
* 行动方法
*/
public void action(){

    command.execute();
}

}
复制代码
  客户端角色类

复制代码
public class Client {

public static void main(String[] args) {
    //创建接收者
    Receiver receiver = new Receiver();
    //创建命令对象,设定它的接收者
    Command command = new ConcreteCommand(receiver);
    //创建请求者,把命令对象设置进去
    Invoker invoker = new Invoker(command);
    //执行方法
    invoker.action();
}

}

二、AudioPlayer系统

小女孩茱丽(Julia)有一个盒式录音机,此录音机有播音(Play)、倒带(Rewind)和停止(Stop)功能,录音机的键盘便是请求者(Invoker)角色;茱丽(Julia)是客户端角色,而录音机便是接收者角色。Command类扮演抽象命令角色,而PlayCommand、StopCommand和RewindCommand便是具体命令类。茱丽(Julia)不需要知道播音(play)、倒带(rewind)和停止(stop)功能是怎么具体执行的,这些命令执行的细节全都由键盘(Keypad)具体实施。茱丽(Julia)只需要在键盘上按下相应的键便可以了。

录音机是典型的命令模式。录音机按键把客户端与录音机的操作细节分割开来。

在这里插入图片描述
源代码
  接收者角色,由录音机类扮演

复制代码
public class AudioPlayer {

public void play(){
    System.out.println("播放...");
}

public void rewind(){
    System.out.println("倒带...");
}

public void stop(){
    System.out.println("停止...");
}

}
复制代码
  抽象命令角色类

复制代码
public interface Command {
/**
* 执行方法
*/
public void execute();
}
复制代码
  具体命令角色类

复制代码
public class PlayCommand implements Command {

private AudioPlayer myAudio;

public PlayCommand(AudioPlayer audioPlayer){
    myAudio = audioPlayer;
}
/**
 * 执行方法
 */
@Override
public void execute() {
    myAudio.play();
}

}
复制代码
复制代码
public class RewindCommand implements Command {

private AudioPlayer myAudio;

public RewindCommand(AudioPlayer audioPlayer){
    myAudio = audioPlayer;
}
@Override
public void execute() {
    myAudio.rewind();
}

}
复制代码
复制代码
public class StopCommand implements Command {
private AudioPlayer myAudio;

public StopCommand(AudioPlayer audioPlayer){
    myAudio = audioPlayer;
}
@Override
public void execute() {
    myAudio.stop();
}

}
复制代码
  请求者角色,由键盘类扮演

复制代码
public class Keypad {
private Command playCommand;
private Command rewindCommand;
private Command stopCommand;

public void setPlayCommand(Command playCommand) {
    this.playCommand = playCommand;
}
public void setRewindCommand(Command rewindCommand) {
    this.rewindCommand = rewindCommand;
}
public void setStopCommand(Command stopCommand) {
    this.stopCommand = stopCommand;
}
/**
 * 执行播放方法
 */
public void play(){
    playCommand.execute();
}
/**
 * 执行倒带方法
 */
public void rewind(){
    rewindCommand.execute();
}
/**
 * 执行播放方法
 */
public void stop(){
    stopCommand.execute();
}

}
复制代码
  客户端角色,由茱丽小女孩扮演

复制代码
public class Julia {
public static void main(String[]args){
//创建接收者对象
AudioPlayer audioPlayer = new AudioPlayer();
//创建命令对象
Command playCommand = new PlayCommand(audioPlayer);
Command rewindCommand = new RewindCommand(audioPlayer);
Command stopCommand = new StopCommand(audioPlayer);
//创建请求者对象
Keypad keypad = new Keypad();
keypad.setPlayCommand(playCommand);
keypad.setRewindCommand(rewindCommand);
keypad.setStopCommand(stopCommand);
//测试
keypad.play();
keypad.rewind();
keypad.stop();
keypad.play();
keypad.stop();
}
}
在这里插入图片描述

三、宏命令

所谓宏命令简单点说就是包含多个命令的命令,是一个命令的组合。

设想茱丽的录音机有一个记录功能,可以把一个一个的命令记录下来,再在任何需要的时候重新把这些记录下来的命令一次性执行,这就是所谓的宏命令集功能。因此,茱丽的录音机系统现在有四个键,分别为播音、倒带、停止和宏命令功能。此时系统的设计与前面的设计相比有所增强,主要体现在Julia类现在有了一个新方法,用以操作宏命令键。
  在这里插入图片描述
源代码
  系统需要一个代表宏命令的接口,以定义出具体宏命令所需要的接口。

复制代码
public interface MacroCommand extends Command {
/**
* 宏命令聚集的管理方法
* 可以添加一个成员命令
/
public void add(Command cmd);
/
*
* 宏命令聚集的管理方法
* 可以删除一个成员命令
*/
public void remove(Command cmd);
}
复制代码
  具体的宏命令MacroAudioCommand类负责把个别的命令合成宏命令。

复制代码
public class MacroAudioCommand implements MacroCommand {

private List<Command> commandList = new ArrayList<Command>();
/**
 * 宏命令聚集管理方法
 */
@Override
public void add(Command cmd) {
    commandList.add(cmd);
}
/**
 * 宏命令聚集管理方法
 */
@Override
public void remove(Command cmd) {
    commandList.remove(cmd);
}
/**
 * 执行方法
 */
@Override
public void execute() {
    for(Command cmd : commandList){
        cmd.execute();
    }
}

}
复制代码
  客户端类Julia

复制代码
public class Julia {

public static void main(String[]args){
    //创建接收者对象
    AudioPlayer audioPlayer = new AudioPlayer();
    //创建命令对象
    Command playCommand = new PlayCommand(audioPlayer);
    Command rewindCommand = new RewindCommand(audioPlayer);
    Command stopCommand = new StopCommand(audioPlayer);
    
    MacroCommand marco = new MacroAudioCommand();
    
    marco.add(playCommand);
    marco.add(rewindCommand);
    marco.add(stopCommand);
    marco.execute();
}

}
在这里插入图片描述

四、命令模式的优点

●  更松散的耦合

命令模式使得发起命令的对象——客户端,和具体实现命令的对象——接收者对象完全解耦,也就是说发起命令的对象完全不知道具体实现对象是谁,也不知道如何实现。

●  更动态的控制

命令模式把请求封装起来,可以动态地对它进行参数化、队列化和日志化等操作,从而使得系统更灵活。

●  很自然的复合命令

命令模式中的命令对象能够很容易地组合成复合命令,也就是宏命令,从而使系统操作更简单,功能更强大。

●  更好的扩展性

由于发起命令的对象和具体的实现完全解耦,因此扩展新的命令就很容易,只需要实现新的命令对象,然后在装配的时候,把具体的实现对象设置到命令对象中,然后就可以使用这个命令对象,已有的实现完全不用变化。

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

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

相关文章

笔记本上使用usb蓝牙适配器

注意 必须先禁用笔记本上原来的蓝牙功能 禁用笔记本原来的蓝牙功能 使用usb蓝牙适配器

openEuler系统远程SSH远程连接

文章目录 1. 本地SSH连接测试2. openEuler安装Cpolar3. 配置 SSH公网地址4. 公网远程SSH连接5. 固定连接SSH公网地址6. SSH固定地址连接测试 欧拉操作系统(openEuler, 简称“欧拉”)是面向数字基础设施的操作系统,支持服务器、云计算、边缘openEuler是面向数字基础设施的操作系…

Latent Topic-aware Multi-Label Classification

X t ^t t and X s ^s s分别是训练和测试输入矩阵 predictive model h of the mapping between X t ^t t and Y t ^t t in the training data can be applied to the testing data&#xff0c;predictive model g of the mapping between X t ^t t and X s ^s s in the input da…

免费SSL证书有效期

免费SSL证书有效期现状 目前市场上主流的免费SSL证书提供商大多遵循行业规范&#xff0c;将免费证书的有效期设为3个月。这意味着每隔三个月&#xff0c;网站管理员必须重新申请、验证并安装新的SSL证书&#xff0c;以维持网站的HTTPS安全连接状态。这种做法已成为行业的常态&…

顶顶通呼叫中心中间件-如何利用机器人话术转接到坐席中

文章目录 前言联系我们实现方法 前言 场景&#xff1a;机器人话术执行到某一节点需要转接到人工坐席中&#xff0c;且呼叫坐席超时后可以返回到机器人话术中&#xff0c;然后继续执行话术剩下的流程。 联系我们 有意向了解呼叫中心中间件的用户&#xff0c;可以点击该链接添加…

MQTT.fx下载使用详解

mqtt.fx是一款基于 Eclipse Paho&#xff0c;使用 Java 语言编写的 MQTT 客户端工具。支持通过 Topic 订阅和发布消息&#xff0c;用来前期和物联网云平台调试非常方便。 &#xff08;一&#xff09;下载软件 傻瓜式安装 链接&#xff1a;https://pan.baidu.com/s/1PxXnuIPN…

基于springboot+vue的医疗挂号管理系统

博主主页&#xff1a;猫头鹰源码 博主简介&#xff1a;Java领域优质创作者、CSDN博客专家、阿里云专家博主、公司架构师、全网粉丝5万、专注Java技术领域和毕业设计项目实战&#xff0c;欢迎高校老师\讲师\同行交流合作 ​主要内容&#xff1a;毕业设计(Javaweb项目|小程序|Pyt…

Tomcat实现java博客项目、状态页及常见配置介绍

目录 一、自建博客 1. 项目背景 2. 操作示例 二、状态页 1. 概述 2. server status 信息状态页 3. manager app 项目管理状态页 4. host manger 虚拟主机管理状态页 三、常见配置 1. 端口8005/tcp安全配置管理 2. tomcat端口号 3. 虚拟主机设置 4. Context配置 一…

我国离子注入设备市场规模不断增加 本土企业仍有较大发展空间

我国离子注入设备市场规模不断增加 本土企业仍有较大发展空间 离子注入是半导体器件和集成电路生产的关键工艺之一&#xff0c;其提供的高精度和高均匀性可以大幅度提高集成电路的成品率。离子注入设备是芯片制造的核心工艺装备。 从全球市场来看&#xff0c;随着科学技术不断进…

Provisional headers are shown报错原因支付宝小程序跳转页面时Ajax请求被杀死

报错 Provisional headers are shown 支付宝小程序一个页面请求没有结束&#xff0c;就跳转到了另一个页面 解决&#xff1a; - 等待请求结束再跳转 - 使用settimeout使进程在宏任务队列不会被杀死 携带参数太多&#xff0c;请求头过大导致支付宝中请求表现为无响应。【在另一…

当Sora风靡,AI风潮吹醒金融科技

以下文章来源&#xff1a;凤凰网 前有OpenAI发布了Sora&#xff0c; 后有苹果放弃了秘密进行了十年的造车项目&#xff0c;转身拥抱AI&#xff0c; 再有国内市场上此起彼伏的AI呐喊声&#xff0c; 一场以AI为主导的新热浪&#xff0c;正在来袭。 当AI的风潮开始兴盛&#x…

【视频转码】基于ZLMediakit的视频转码技术概述

一、概述 zlmediakit pro版本支持基于ffmpeg的转码能力&#xff0c;在开源版本强大功能的基础上&#xff0c;新增支持如下能力&#xff1a; 1、音视频间任意转码(包括h265/h264/opus/g711/aac等)。2、基于配置文件的转码&#xff0c;支持设置比特率&#xff0c;codec类型等参…

js设计模式:解释器模式

作用: 对文本进行解释和编译的时候,就会用到解释器模式 比如你写了一段js代码,js引擎就会去解释并执行这段代码 webpack中的各种loader就是用来解释各种文件类型的,并将其解释为js可识别的代码 示例: //翻译词库const wordList [{text:韩信前期有蓝有红,必须拿二杀。你要是…

电脑解锁后黑屏有鼠标--亲测!!不需要重装系统!!

问题&#xff1a;上周电脑黑屏&#xff0c;只有鼠标&#xff0c;鼠标还不能右键&#xff01;&#xff01; 中招&#xff1a;win10系统最新版火绒安全 &#xff0c;那你有概率获得开机黑屏套餐一份。 原因是&#xff1a;火绒把我们的explorer删除了导致黑屏&#xff0c;这个文…

医院床旁交互系统概述 -智慧护理-全视通

全视通床旁交互系统是一种先进的医疗信息技术解决方案&#xff0c;旨在改善病患与医疗团队之间的沟通与交流。该系统通过集成多种高科技设备&#xff0c;为病患在病床边提供了一站式的信息交互平台&#xff0c;从而优化了医疗服务流程&#xff0c;提升了医疗体验。 首先&#x…

C# LaMa Image Inpainting 图像修复 Onnx Demo

目录 介绍 效果 模型信息 项目 代码 下载 LaMa Image Inpainting 图像修复 Onnx Demo 介绍 gihub地址&#xff1a;https://github.com/advimman/lama &#x1f999; LaMa Image Inpainting, Resolution-robust Large Mask Inpainting with Fourier Convolutions, WAC…

Python 应用程序编程接口库之pywin32使用详解

概要 在Python的世界里,有许多优秀的第三方库可以帮助开发者更轻松地处理各种任务。其中,pywin32库是一个特别引人注目的工具,它提供了对Windows API的完整访问,使得开发者能够利用Python来编写强大的Windows应用程序,从简单的脚本到复杂的桌面应用,pywin32都能胜任。 什…

anaconda创建虚拟环境(第一次玩)

首先需要打开anaconda prompt&#xff0c;打开后需要等待一会&#xff0c;他要加载。 然后你输入下面的代码&#xff0c;其中环境名和python版本可以自定义 conda create -n 环境名 python3.6比如我的是 conda create -n mnist python3.7.0 等待一会&#xff0c;中途需要你输…

【论文精读】基于知识图谱关系路径的多跳智能问答模型研究

&#x1f497;&#x1f497;&#x1f497;欢迎来到我的博客&#xff0c;你将找到有关如何使用技术解决问题的文章&#xff0c;也会找到某个技术的学习路线。无论你是何种职业&#xff0c;我都希望我的博客对你有所帮助。最后不要忘记订阅我的博客以获取最新文章&#xff0c;也欢…

Axure 入门文档 文件格式 全局样式 元件居中

文件格式 .rp 原型文件.rplib:元件库文件.rpteam 团队项目文件.html 项目网页文件 批量设置居中 选中多个&#xff0c;然后上方任务栏即可设置 设置自定义页面视图尺寸 项目-自适应视图设置 点击页面空白处就可以使用 添加元件说明 当一个元件创建好&#xff0c;可以设…