设计模式之Command

ops/2024/10/19 23:36:56/

一、Command模式基本介绍

Command模式,也称为行动模式或事务模式,用于将请求封装为一个对象,从而实现行为的解耦和灵活性。 这种模式特别适用于需要记录、撤销或重做操作的情况,因为它允许系统在运行时动态地处理请求。

定义与结构: Command模式定义了一个命令的接口(Command),声明了执行的方法。具体命令(ConcreteCommand)是命令接口的实现,通常持有接收者(Receiver)并调用其功能来完成命令要执行的操作。接收者是真正执行命令的对象,而客户端(Client)创建具体的命令对象并设置其接收者。

角色与协作: 在这个模式中,有几个关键角色:命令(Command)、具体命令(ConcreteCommand)、接收者(Receiver)、调用者(Invoker)和客户端(Client)。客户端创建具体的命令对象并设置其接收者。调用者持有命令对象,并通过调用命令对象的Execute方法来提交请求。

应用场景: Command模式广泛应用于需要高灵活性和可维护性的系统中,如菜单命令、撤销操作、游戏动作组合等。通过将操作封装为命令对象,系统可以在不修改原有代码的情况下增加新的操作或修改已有操作的行为。

优点与缺点: 优点包括类间的解耦、可扩展性以及支持撤销操作等。缺点是如果系统中存在大量的命令,可能会导致Command类的数量增多,增加系统的复杂性。

 二、场景实现例子

场景:实现一个拨号功能,要求不同的按钮播放不同的声音,最后组合后拨号。

先看Client代码 

package command;/*** 负责创建各个类,并且组装命令*/
public class Client {public static void main(String[] args) {Invoker invoker = new Invoker();Receiver receiver = new Receiver();invoker.addCommand(new NumberCommand(1, receiver));invoker.addCommand(new NumberCommand(3, receiver));invoker.addCommand(new NumberCommand(5, receiver));invoker.addCommand(new NumberCommand(3, receiver));invoker.addCommand(new NumberCommand(5, receiver));invoker.addCommand(new NumberCommand(17, receiver));invoker.addCommand(new DialCommand(receiver));invoker.dialPhone();}
}

Invoker

package command;import java.util.ArrayList;
import java.util.List;/*** 拨号器*/
public class Invoker {private List<Command> commandList;public Invoker() {commandList = new ArrayList<Command>();}public void addCommand(Command command) {commandList.add(command);}/*** Command的组合调用,可以灵活用于命令编排,类似游戏中的动作组合,非常有用*/public void dialPhone() {for (Command command : commandList) {command.execute();}commandList.clear();}}

命令接口Command

package command;public interface Command {public void execute();}

 数字类号码播放命令

package command;/*** 数字按钮*/
public class NumberCommand implements Command {private Integer num;private Receiver receiver;public NumberCommand(Integer num, Receiver receiver) {this.num = num;this.receiver = receiver;}@Overridepublic void execute() {System.out.println("播放按钮" + num + "声音,并亮灯");receiver.addNum(num);}}

 拨号按钮命令

package command;/*** 拨号按钮*/
public class DialCommand implements Command {private Receiver receiver;public DialCommand(Receiver receiver) {this.receiver = receiver;}@Overridepublic void execute() {receiver.dial();}
}

 干苦活累活的命令接收者Receiver

package command;import java.util.ArrayList;
import java.util.List;/*** 命令的接收者,这里输入号码和拨号,都是同一个接收者,我们定义两个方法*/
public class Receiver {// 存储电话号码private List<Integer> numList;public Receiver() {this.numList = new ArrayList<Integer>();}public void addNum(Integer num) {System.out.println("本地存储按按钮数字:" + num);numList.add(num);}public void dial() {System.out.println("拨号中,号码为" + numList);numList.clear();}
}

Client代码执行效果:

 

三、结束语

通过上面一个简单的例子,让我们对命令模式的灵活性有很好的理解,现实场景中,使用命令模式,比较复杂的应该是接收者的实现。学了这个后,我们以后对各种开关按钮等功能实现,软件界面的执行及回撤等,都可以使用命令模式。

如果觉得不错,请收藏或者点赞支持,小红点是我持续更新的动力之一,感谢~


http://www.ppmy.cn/ops/56307.html

相关文章

设计模式探索:适配器模式

1. 适配器模式介绍 1.1 适配器模式介绍 适配器模式&#xff08;adapter pattern&#xff09;的原始定义是&#xff1a;将一个类的接口转换为客户期望的另一个接口&#xff0c;适配器可以让不兼容的两个类一起协同工作。 适配器模式的主要作用是把原本不兼容的接口&#xff0c…

实现桌面动态壁纸(二)

目录 前言 一、关于 WorkerW 工作区窗口 二、关于窗口关系 2.1 窗口以及窗口隶属关系 2.2 桌面管理层窗口组分简析 2.3 厘清两个概念的区别 2.4 关于设置父窗口 三、编写代码以供在 Vista 上实现 3.1 方法二&#xff1a;子类化并自绘窗口背景 四、初步分析桌面管理层…

雷电模拟如何换ip地址 手机模拟器ip修改方法

很多游戏爱好者会使用雷电模拟器多开窗口&#xff0c;若模拟器窗口开多了&#xff0c;IP地址是一样的就怕有限制&#xff0c;很容易被游戏后台检测到&#xff0c;从而产生被封号的风险。 那么怎么更换自己电脑手机模拟器IP地址呢&#xff0c;今天就教大家一个修改模拟器IP地址的…

绝区陆--大语言模型的幻觉问题是如何推动科学创新

介绍 大型语言模型 (LLM)&#xff08;例如 GPT-4、LLaMA-2、PaLM-2、Claude-2 等&#xff09;已展示出为各种应用生成类似人类文本的出色能力。然而&#xff0c;LLM 的一个鲜为人知的方面是它们倾向于“产生幻觉”或生成不正确或没有根据的事实陈述。我不认为这仅仅是一个限制…

Oracle数据库自带的内置表和视图、常用内部视图

文章目录 一.Oracle数据库自带的内置表和视图1.dba_开头表2.user_开头表3.v$开头表4.all_开头表5.session_开头表6.index_开头表 三.按组分的几组重要的性能视图1.System的over view2.某个session的当前情况3.SQL的情况4.Latch/lock/ENQUEUE5.IO方面的 分类类别关系群集、表、视…

AE-图层

目录 图层初体验 项目、合成和图层的关系 图层的通用参数 锚点&#xff08;快捷键A&#xff09; 位置&#xff08;快捷键P&#xff09; 缩放&#xff08;快捷键S&#xff09; 旋转&#xff08;快捷键R&#xff09; 不透明度&#xff08;快捷键T&#xff09; 向后平移锚…

【ai】决策树

决策树 决策树是一种监督学习算法,主要用于分类和回归任务。它通过对数据进行树状结构的分割来进行预测。决策树的主要优点包括易于理解和解释、处理数值型和分类型数据的能力以及对特征缩放不敏感。以下是决策树的基本概念和主要应用。决策树的基本概念 节点(Node): 根节…

代码随想录打卡第十六天

代码随想录–二叉树部分 day16 二叉树第四天 文章目录 代码随想录--二叉树部分一、力扣513--找树左下角的值二、力扣112--路径总和三、力扣106--从中序与后序遍历序列构造二叉树 一、力扣513–找树左下角的值 代码随想录题目链接&#xff1a;代码随想录 给定一个二叉树的 根节…