【行为型模式】命令模式

server/2024/9/24 10:15:17/

一、命令模式概述

        命令模式的定义将“请求”封装成对象,以便使用不同的请求、队列或者日志来参数化其他对象。命令模式也支持可撤销的操作。(对象行为型)

  • 命令模式优缺点
    • 优点
      • 1.类间解耦:调用者角色与接收者角色之间没有任何依赖关系,调用者实现功能时只需调用Command 抽象类的execute方法就可以,不需要了解到底是哪个接收者执行。
      • 2.可扩展性:Command的子类可以非常容易地扩展,而调用者Invoker和高层次的模块Client不产生严 重的代码耦合。
      • 3.命令模式结合其他模式会更优秀:命令模式可以结合责任链模式,实现命令族解析任务;结合模板方法模式,则可以减少 Command子类的膨胀问题。
    • 缺点
      • 如果有N个命令,问题就出来 了,Command的子类就可不是几个,而是N个,这个类膨胀得非常大。
  • 适用环境
    • 1.需要先将一个函数登记上,然后再以后调用此函数时,就需要使用命令模式,其实这就是回调函数
    • 2.有时候需要向某些对象发送请求,但是并不知道请求的接收者是谁,也不知道被请求的操作是什么。此时希望用一种松耦合的方式来设计程序,使得请求发送者和请求接收者能够消除彼此之间的耦合关系。

二、代码实现

        命令模式包含四个角色:

  • Command命令角色(抽象):声明执行命令的接口,拥有执行命令的抽象方法 execute ();
  • ConcreteCommand(具体命令):是抽象命令类的具体实现类,它拥有接收者对象,并通过调用接收者的功能来完成命令要执行的操作;
  • Invoker调用者角色:是请求的发送者,它通常拥有很多的命令对象,并通过访问命令对象来执行相关请求,它不直接访问接收者。
  • Receiver接受者角色:执行命令功能的相关操作,是具体命令对象业务的真正实现者;
        2.1 抽象命令(Command接口)
java">package Command.remoteControl;
//命令接口
public interface Command {//执行命令public void execute();
}
        2.2 具体命令(LightOnCommand、LightOffCommand、NoCommand、StereoOnWithCDCommand、StereoOffCommand)
java">package Command.remoteControl;
//具体命令,接受并执行命令,开灯命令
public class LightOnCommand implements Command {private Light light;public LightOnCommand(Light light){this.light = light;}@Overridepublic void execute() {// TODO Auto-generated method stublight.on();}}
java">package Command.remoteControl;
//具体命令,接受并执行命令,关灯
public class LightOffCommand implements Command {private Light light;public LightOffCommand(Light light){this.light = light;}@Overridepublic void execute() {// TODO Auto-generated method stublight.off();}}
java">package Command.remoteControl;
//具体命令,接受并执行命令,无任何响应命令
public class NoCommand implements Command {@Overridepublic void execute() {// TODO Auto-generated method stub}}
java">package Command.remoteControl;
//具体命令,接受并执行命令,开CD且音量为14
public class StereoOnWithCDCommand implements Command {private Stereo stereo;public StereoOnWithCDCommand(Stereo stereo) {this.stereo = stereo;}@Overridepublic void execute() {// TODO Auto-generated method stubstereo.on();stereo.setCD();stereo.setVolume(14);}}
java">package Command.remoteControl;
//具体命令,接受并执行命令,关音响
public class StereoOffCommand implements Command {private Stereo stereo;public StereoOffCommand(Stereo stereo) {this.stereo = stereo;}@Overridepublic void execute() {// TODO Auto-generated method stubstereo.off();}}
        2.3 Invoker(Light、Stereo)
java">package Command.remoteControl;
//Invoker,发送开关请求,电灯
public class Light {String position;public Light(String position) {this.position = position;}public void on(){System.out.println(position +" light is on...");}public void off(){System.out.println(position+" light is off...");}}
java">package Command.remoteControl;
//Invoker,发送开关音量请求,音响
public class Stereo {String position;public Stereo(String position) {this.position = position;}public void on(){System.out.println(position + " stereo is on...");}public void off(){System.out.println(position + " stereo is off...");}public void setCD() {System.out.println(position+ " stereo is set for CD input...");}public void setVolume(int volume) {System.out.println(position+" stereo volume set to " + volume);}}
         2.4 接收者(RemoteControl)
java">package Command.remoteControl;
//Receiver:干活,遥控器
public class RemoteControl {//开灯private Command[] onCommands;//关灯private Command[] offCommands;public RemoteControl(){//初始化开与关的数组onCommands = new Command[7];offCommands = new Command[7];NoCommand noCommand = new NoCommand();for(int i=0;i<7;i++){onCommands[i] = noCommand;offCommands[i] = noCommand;}}/*** 设置按钮指令* @param position* @param onCommand* @param offCommand*/public void setCommand(int position,Command onCommand, Command offCommand){onCommands[position] = onCommand;offCommands[position] = offCommand;}//按下开或关,硬件就负责调用对应的方法public void onButtonWasPushed(int position) {onCommands[position].execute();}public void offButtonWasPushed(int position) {offCommands[position].execute();}public String toString() {StringBuffer stringBuff = new StringBuffer();stringBuff.append("\n------ Remote Control -------\n");for (int i = 0; i < onCommands.length; i++) {stringBuff.append("[slot " + i + "] " + onCommands[i].getClass().getName()+ "    " + offCommands[i].getClass().getName() + "\n");}return stringBuff.toString();}}
        2.5 main方法实现命令模式
java">package Command.remoteControl;public class RemoteLoader {public static void main(String[] args) {// TODO Auto-generated method stubRemoteControl remoteControl = new RemoteControl();Light livingRoomLight = new Light("Living Room");LightOnCommand livingRoomLightOn = new LightOnCommand(livingRoomLight);LightOffCommand livingRoomLightOff = new LightOffCommand(livingRoomLight); Stereo stereo = new Stereo("Living Room");StereoOnWithCDCommand setreoOnWithCD = new StereoOnWithCDCommand(stereo);StereoOffCommand setreoOff = new StereoOffCommand(stereo);//加载到遥控器槽中remoteControl.setCommand(0, livingRoomLightOn, livingRoomLightOff);remoteControl.setCommand(1, setreoOnWithCD, setreoOff);//打印遥控器插槽和被指定的命令System.out.println(remoteControl);//按遥控器remoteControl.onButtonWasPushed(0);remoteControl.offButtonWasPushed(0);remoteControl.onButtonWasPushed(1);remoteControl.offButtonWasPushed(1);}}
        2.6 UML图

三、代码结构


http://www.ppmy.cn/server/9797.html

相关文章

数据挖掘实验(Apriori,fpgrowth)

Apriori&#xff1a;这里做了个小优化&#xff0c;比如abcde和adcef自连接出的新项集abcdef&#xff0c;可以用abcde的位置和f的位置取交集&#xff0c;这样第n项集的计算可以用n-1项集的信息和数字本身的位置信息计算出来&#xff0c;只需要保存第n-1项集的位置信息就可以提速…

C语言C++面试题 (包答案)

1 变量的声明和定义有什么区别 变 量 的 定 义 为 变 量 分 配 地 址 和 存 储 空 间 &#xff0c; 变 量 的 声 明 不 分 配 地 址 。 一 个 变 量 可 以 在 多 个 地 方 声 明 &#xff0c; 但 是 只 在 一 个 地 方 定 义 。 加 入 e x t e r n 修 饰 的 是 变 量 的 声 明…

第十二届蓝桥杯C/C++ B组 杨辉三角形(二分查找+思维)

3418. 杨辉三角形 - AcWing题库 题目描述: 思路&#xff1a; 从上图片中&#xff0c;我们可以看出来这是一个对称图形&#xff0c;所以我们只看左半部分就可以了&#xff0c;我们一行一列去做数据量是1e9这样会很麻烦&#xff0c;所以我们这里做一个思想转换&#xff0c;斜着…

苍穹外卖day10(1)Spring Task、 订单状态定时处理

文章目录 前言一、Spring Task1.1 概述1.2 cron表达式1.3 使用步骤 二、订单状态定时处理1. 业务规则2. 代码实现 前言 Spring Task用于在指定时间处理某个业务逻辑&#xff0c;在本项目中体现在订单状态定时处理&#xff0c;包括“下单后未支付&#xff08;订单超时自动取消&…

物联网通信中NB-IoT、Cat.1、Cat.M该如何选择?

物联网通信中NB-IoT、Cat.1、Cat.M该如何选择? 参考链接:物联网通信中NB-IoT、Cat.1、Cat.M该如何选择?​​ 在我们准备设计用于大规模联网的物联网设备时,选择到适合的LTE IoT标准将是我们遇到的难点。这是我们一开始设计产品方案就需要解决的一个问题,其决定我们设备需…

day07 51单片机-串口通信

51 单片机-串口通信 1 串口通信 1.1 需求描述 本案例讲解如何通过串口和PC以9600波特率,无校验位、1停止位通信。最终实现PC向单片机发送字符串,单片机回复PC。本案例中采用串口1通信。 1.2 硬件设计 1.2.1 串口工作原理 串口是将数据按照比特逐一发送的通信接口。在串…

学习前端第二十六天(对象 —— 原始值转换、原始类型的方法、数字类型)

一、对象 —— 原始值转换 目的&#xff1a;对象是如何转换为原始值的&#xff0c;以及如何对其进行自定义 obj[Symbol.toPrimitive] function(hint) { // 这里是将此对象转换为原始值的代码 // 它必须返回一个原始值 // hint "string"、"number" 或…

数据结构与算法解题-20240422

这里写目录标题 一、2. 两数相加二、67. 二进制求和三、415. 字符串相加四、LCS 01. 下载插件五、71. 简化路径 一、2. 两数相加 给你两个 非空 的链表&#xff0c;表示两个非负的整数。它们每位数字都是按照 逆序 的方式存储的&#xff0c;并且每个节点只能存储 一位 数字。 …