OOP设计模式[JAVA]——04命令模式

SECS/GSM 测试工具 SecsExpress 的配置与实战应用 本文详细介绍了半导体设备通讯测试工具SecsExpress的配置与实战应用。作为专业的SECS/GSM协议调试工具,它能模拟Host与设备端进行双向测试,帮助工程师快速部署、验证通讯链路,并高效排查与RMS系统或真实设备间的联调问题,是提升半导体工厂设备集成与维护效率的利器。 阅读详情

命令模式

命令模式的意图

命令模式属于对象的行为模式。别名又叫:Action或Transaction。

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

命令模式的结构



命令模式的参与者

  • Command
    ——声明一个给所有具体命令类的抽象接口。这是一个抽象角色,通常由一个Java接口或Java抽象类实现。
  • ConcreteCommand
    ——将一个接收者对象绑定于一个动作
    ——调用接收者相应的操作,以实现execute
  • Client
    ——创建一个具体命令对象并设定它的接收者
  • Invoker
    ——负责调用命令对象执行请求。
  • Receiver
    ——知道如何实施与执行一个请求相关的操作。任何类都可能作为一个接收者。

命令模式的活动序列


  1. 客户端创建了一个ConcreteCommand对象,并指明了接收者。
  2. 请求者对象保存了ConcreteCommand对象。
  3. 请求者对象通过调用action()方法发出请求。如果命令是撤消的,那么ConcreteCommand保存了调用execute()方法之前的状态。
  4. ConcreteCommand对象调用接收的一方的方法执行请求。

命令模式的使用场景

家电遥控器,该遥控器的原型如下:

  1. 有7个可编程的插槽(每一个都可以指定到一个不同的家电装置)
  2. 每个插槽都有对应的开关按钮
  3. 具备一个整体的撤销按键

下面我们来看看最简单的实现。

Command:抽象命令接口

/**
 * 抽象接口 Command
 * @author nick
 *
 */
public interface Command {
    public void execute();  //非常简单,只需要一个方法:execute()
}
ConcreteCommand:具体命令类

/**
 * 具体命令类
 * @author nick
 *
 */
public class LightOnCommand implements Command {

    //构造器传入了接收对象,以便让这个命令控制,然后记录在实例变量中。
    //一旦调用execute()方法,就由这个对象成为接收者,负责接收请求
    public LightOnCommand(Light light) {
        super();
        this.light = light;
    }

    @Override
    public void execute() {
        // 这个execute()方法调用接收对象的on()方法
        light.on();
    }

    Light light;
}
Client:客户端

/**
 * 遥控器测试类------>客户端
 * @author nick
 *
 */
public class RemoteControlTest {

    /**
     * @param args
     */
    public static void main(String[] args) {
        // 遥控器就是调用者,会传入一个命令对象,可以用来发出请求
        SimpleRemoteControl remote = new SimpleRemoteControl();
        //创建一个电灯对象,此对象就是请求的接收者
        Light light = new Light();
        //创建一个命令,然后将接收者传递给它
        LightOnCommand lightOn = new LightOnCommand(light);
        
        remote.setCommand(lightOn); //把命令传给调用者
        remote.buttonWasPressed();  //模拟遥控器的按钮按下动作
    }

}
invoker:调用者

/**
 * 遥控器类------>调用者
 * 
 * @author nick
 */
public class SimpleRemoteControl {
    Command slot;   //有一个插槽持有命令,而这个命令控制着一个装置

    public SimpleRemoteControl() {
    }

    public void setCommand(Command command) {   //用来设置插槽控制的命令
        slot = command;
    }

    public void buttonWasPressed() {            //遥控器按钮按下时,使得当前命令衔接插槽
        slot.execute();
    }
}
Receiver:接收者

/**
 * 电灯对象------>接收者
 * @author nick
 *
 */
public class Light {
    int level;

    public Light() {}

    public void on() {
        level = 100;
        System.out.println("Light is on");
    }

    public void off() {
        level = 0;
        System.out.println("Light is off");
    }

    public void dim(int level) {
        this.level = level;
        if (level == 0) {
            off();
        }
        else {
            System.out.println("Light is dimmed to " + level + "%");
        }
    }

    public int getLevel() {
        return level;
    }
}
模拟结果输出如下:
Light is on

以上只是单个命令的操作,如果我们需要添加一个LightOff的命令呢,那该怎么办?看下面:

/**
 * 具体命令类---->关闭电灯
 * @author nick
 *
 */
public class LightOffCommand implements Command {

    //构造器传入了接收对象,以便让这个命令控制,然后记录在实例变量中。
    //一旦调用execute()方法,就由这个对象成为接收者,负责接收请求
    public LightOffCommand(Light light) {
        super();
        this.light = light;
    }

    @Override
    public void execute() {
        // 这个execute()方法调用接收对象的off()方法
        light.off();
    }

    Light light;
}
/**
 * 遥控器测试类------>客户端
 * @author nick
 *
 */
public class RemoteControlTest {
    /**
     * @param args
     */
    public static void main(String[] args) {
        // 遥控器就是调用者,会传入一个命令对象,可以用来发出请求
        SimpleRemoteControl remote = new SimpleRemoteControl();
        //创建一个电灯对象,此对象就是请求的接收者
        Light light = new Light();
        //创建一个命令,然后将接收者传递给它
        LightOnCommand lightOn = new LightOnCommand(light);
        LightOffCommand lightOff = new LightOffCommand(light);  //添加LightOff命令
        
        remote.setCommand(lightOn); //把命令传给调用者
        remote.setCommand(lightOff);
        remote.buttonWasPressed();  //模拟遥控器的按钮按下动作
    }
}

 好了,其他几个控制命令,可以按这个去添加即可。但是我们别忘了,Command模式不是说还可以提供撤消和恢复功能吗,那这个功能我们又该如何实现呢?

因为每个控制按钮都需要实现撤消功能,所以我们要在抽象命令的接口中定义该撤消功能的方法:

/**
 * 抽象接口 Command
 * @author nick
 *
 */
public interface Command {
    public void execute();  // 非常简单,只需要一个方法:execute()
    public void undo();     // 添加一个撤消方法
}

具体命令类的实现:

/**
 * 具体命令类
 * @author nick
 *
 */
public class LightOnCommand implements Command {

    //构造器传入了接收对象,以便让这个命令控制,然后记录在实例变量中。
    //一旦调用execute()方法,就由这个对象成为接收者,负责接收请求
    public LightOnCommand(Light light) {
        super();
        this.light = light;
    }

    @Override
    public void execute() {
        // 这个execute()方法调用接收对象的on()方法
        light.on();
    }

    @Override
    public void undo() {
        // 实现抽象命令中的撤消功能,该撤消动作就是电灯对象的上一个动作(light off)
        System.out.println("Ready to undo---->");
        light.off();
    }

    Light light;
}
/**
 * 具体命令类---->关闭电灯
 * @author nick
 *
 */
public class LightOffCommand implements Command {

    //构造器传入了接收对象,以便让这个命令控制,然后记录在实例变量中。
    //一旦调用execute()方法,就由这个对象成为接收者,负责接收请求
    public LightOffCommand(Light light) {
        super();
        this.light = light;
    }

    @Override
    public void execute() {
        // 这个execute()方法调用接收对象的off()方法
        light.off();
    }

    public void undo() {
        // 实现抽象命令中的撤消功能,该撤消动作就是电灯对象的上一个动作(light on)
        System.out.println("Ready to undo---->");
        light.on();
    }

    Light light;
}

调用者类

/**
 * 遥控器类------>调用者
 * 
 * @author nick
 */
public class SimpleRemoteControl {
    Command onCommand;
    Command offCommand;
    Command undoCommand;

    public SimpleRemoteControl() {
    }

    public void setCommand(Command onCom, Command offCom) {//用来设置插槽控制的命令
        onCommand = onCom;
        offCommand = offCom;
    }

    public void onButtonWasPressed() {            //开电灯按钮按下,执行打开电灯命令
        onCommand.execute();
        undoCommand = onCommand;
    }
    
    public void offButtonWasPressed() {            //关电灯按钮按下,执行关闭电灯命令
        offCommand.execute();
        undoCommand = offCommand;
    }
    
    public void undoButtonWasPressed() {            //撤消按钮按下,执行撤消动作
        undoCommand.undo();
    }
}
客户端

/**
 * 遥控器测试类------>客户端
 * @author nick
 *
 */
public class RemoteControlTest {
    /**
     * @param args
     */
    public static void main(String[] args) {
        // 遥控器就是调用者,会传入一个命令对象,可以用来发出请求
        SimpleRemoteControl remote = new SimpleRemoteControl();
        //创建一个电灯对象,此对象就是请求的接收者
        Light light = new Light();
        //创建一个命令,然后将接收者传递给它
        LightOnCommand lightOn = new LightOnCommand(light);
        LightOffCommand lightOff = new LightOffCommand(light);  //添加LightOff命令
        
        remote.setCommand(lightOn, lightOff);
        
        remote.onButtonWasPressed();  //模拟遥控器的按钮按下动作
        remote.undoButtonWasPressed();
        System.out.println("++++++++++++++++++++");
        remote.offButtonWasPressed();
        remote.undoButtonWasPressed();
    }
}

测试结果如下:

Light is on
Ready to undo---->
Light is off
++++++++++++++++++++
Light is off
Ready to undo---->
Light is on

命令模式的效果

Command模式有以下效果:

  1. Command模式将调用操作的对象与知道如何实现该操作的对象解耦
  2. Command是头等的对象。它们可像其他的对象一样被操作和扩展
  3. 可将多个命令装配成一个复合命令。
  4. 增加新的Command很容易,无需改变已有的类

命令模式的实现

实现command模式须考虑的问题有如下:

  1. 一个命令对象应达到何种智能程度     命令对象的能力可大可小。一个极端是它仅确定一个接收者和执行该请求的动作。另一个极端是它自己实现所有功能,根本不需要接收对象。当需要定义与已有的类无关的命令,当没有合适的接收者,或当一个命令隐式地知道它的接收者时,可以使用后一极端方式。在这两个极端间的情况是命令对象有足够的信息可以动态的找到它们的接收者。
  2. 支持取消(undo)和重做(redo)    如果Command提供方法逆转它们操作的执行(undo),就可支持取消和重做功能。为达到这个目的,ConcreteCommand类可能需要存储额外的状态信息。这个状态包括:
    • 接收者对象,它真正执行处理该请求的各操作。
    • 接收者上执行操作的参数
    • 如果处理请求的操作会改变接收者对象中的某些值,那么这些值也必须先存储起来。接收者还必须提供一些操作,以使该命令可将接收者恢复到它先前的状态。
      若应用只支持一次取消操作,那么只需存储最近一次被执行的命令。而若要支持多级的取消和重做,就需要有一个已被执行命令的历史表列(history list),该表列的最大长度决定了取消和重做的级数。历史表列存储了已被执行的命令序列。向后遍历该表列并逆向执行( r e v e r s e - e x e c u t i n g )命令是取消它们的结果;向前遍历并执行命令是重执行它们。有时可能不得不将一个可撤消的命令在它可以被放入历史列表中之前先拷贝下来。这是因为执行原来的请求的命令对象将在稍后执行其他的请求。如果命令的状态在各次调用之间会发生变化,那就必须进行拷贝以区分相同命令的不同调用。
  3. 避免取消操作过程中的错误积累
ATE自动化测试设备:硬件与软件的完美协同 本文深入解析了ATE自动化测试设备如何通过硬件与软件的完美协同,实现高效、精准的电子产品测试。文章详细阐述了ATE系统的硬件架构(如测试控制器、仪器模块、开关矩阵)与软件层次(如测试管理、仪器控制、数据分析),并结合实战案例,揭示了软硬件协同设计在提升测试效率与可靠性中的关键作用。 阅读详情

相关推荐

从BIOS到路由器:深入拆解SPI NOR Flash的硬件连接与‘芯片内执行’(XIP)奥秘

本文深入解析SPI NOR Flash的硬件连接与‘芯片内执行’(XIP)技术,从BIOS到路由器的应用场景出发,详细介绍了其架构精髓、典型连接方案、时序设计及性能优化方法。通过实际案例和参数对比,帮助开发者掌握NOR Flash在嵌入式系统中的关键作用与设计技巧,提升电路设计效率与可靠性。

weixin_30522183的博客 492

命令模式

 命令模式的作用? (1)命令模式能够较容易地设计一个命令队列。 (2)在需要的情况下,可以较容易地将命令记入日志。 (3)允许接收请求的一方决定是否要否决请求。 (4)可以容易地实现对请求的撤销和重做。 (5)由于加进新的具体命令类不影响其他的类,因此增加新的具体命令类很容易。 (6)命令模式把请求一个操作的对象与知道怎么执行一个操作的对象分隔开。 什么是命令模式?

步步为赢的专栏 433

学习记录——SIMPACK生成轨道谱文件的方法

生成轨道谱文件的方法,可以用于实测轨道谱导入和自制轨道谱导入仿真

weixin_51965897的博客 7804

JAVA23种设计模式——命令模式

命令模式,就是把客户端(看作main方法)操作一个功能类的过程,单独抽出来作为一个独立的对象。 比如我们用游戏手柄打游戏,我们操控游戏手柄上的前进、后退、攻击等按键来发送我们的请求到游戏角色(请求接收者),游戏角色进行前进、后退、攻击的行为,先看图: 归纳一下基本结构: 玩家,视作main方法 游戏手柄,invoke类,有着所有操作的按钮(对命令类的引用) 命令接口(把各种命令独立出来作为单...

free_journey的博客 219

Ceres Solver:从入门到使用

Ceres Solver是谷歌开源的C++非线性优化库,能够解决有约束或无约束条件下的非线性最小二乘问题。2010年之后大量的运用在谷歌的产品开发中,尤其在谷歌开源的cartographer中被大量的使用。 ceres可以在Linux,Windows,macOS,Andrioid,IOS系统进行安装使用,详情可查看下方的官网链接。 Ceres Solver 官网:http://ceres-solver.org/

非晚非晚的博客 1万+

ADS新手必看:ICCAP数据导入与导出CSV的完整流程(附常见问题解决)

本文为ADS新手详细讲解了如何将ICCAP测试数据导入ADS进行仿真分析,并导出为通用CSV格式的完整流程。内容涵盖文件格式解析、导入设置、数据验证、处理技巧及常见问题排查,重点解决了数据文件导入过程中的兼容性与单位映射等核心难点,帮助射频工程师高效连接测量与仿真环节。

peace的博客 558

设计模式(3)——OOP原则

从最开始接触的Python到现在的C#,这些都是面向对象的编程语言,那么什么是面向对象编程呢?在最开始学习Python的时候,一直都在学习基本的数据结构,依然是面向过程编程,很难对程序语言有较深的理解,在学习C#的时候,我渐渐开始接触类、接口等概念,然而真正开始理解并应用这些概念可花费了不少时间,随后我也渐渐发现,OOP技术的强大之处与魅力所在。 在此总结一下面向对象编程的好处与部分原则。 面...

xy_learning的博客 261

Full Range && Limit Range

Full Range && Limit Range1 Full range和Limit Range定义2 为什么会需要Limit Range3 用Full range去显示limit Range图片4 YUV转RGB5 额外 1 Full range和Limit Range定义 我们知道,对于RGB和YUV的色彩空间来说,有个位深(bit-depth)的概念;位深是指记录图像每个像素的色彩通道时所使用的bit数,常见的RGB888,YUV420-8bit。以RGB888为例,其代表R G B

zjhcj1的博客 1万+

JAVA设计模式--命令模式

命令 (Command) 模式又叫作动作 (Action) 模式或事务 (Transaction) 模式,是一种对象的行为模式。将一个请求封装为一个对象,从而使你可用不同的请求对客户进行参数化;对请求排队或记录请求日志,以及支持可撤消的操作。命令模式的本质:封装请求设计意图:命令模式通过将请求封装到一个命令 (Command) 对象中,实现了请求调用者和具体实现者之间的解耦。命令模式是对命令的封装。命令模式把发出命令的责任和执行命令的责任分割开,委派给不同的对象。

贵公子丶笔记 1373

51单片机计算器(源程序+流程图+答辩报告+综合设计)

保姆级讲解!C语言编程,使用51单片机及LCD1602显示屏实现!

m0_57007304的博客 2万+

【WRF-Urban】URBPARM_LCZ.TBL 查找表解释及内容

URBPARM_LCZ.TBL 查找表解释及内容

WW、forever的博客 1754

JAVA设计模式之命令模式

转自http://www.kongzid.com/archives/design17,命令模式(Command Pattern)是一种数据驱动的设计模式,它属于行为型模式。其别名为动作(Action)模式或事务(Transaction)模式。请求以命令的形式包裹在对象中,并传给调用对象。调用对象寻找可以处理该命令的合适的对象,并把该命令传给相应的对象,该对象执行命令。(将一个请求封装成一个对象,从而使您可以用不同的请求对客户进行参数化。) 命令...

孔子说 3455

16、树莓派Pico W:蓝牙与Wi-Fi应用指南

本文介绍了树莓派Pico W在蓝牙与Wi-Fi通信方面的应用,涵盖蓝牙配对原理、使用HC-06模块实现手机远程控制LED和传输内部温度,以及通过Wi-Fi进行网络连接、扫描和UDP协议下的设备控制。文章包含详细电路连接、代码实现与测试步骤,并提供拓展建议、常见问题解决方法及开发注意事项,帮助读者快速掌握基于Pico W的无线通信项目开发,适用于物联网入门与实践场景。

sun99的博客 290

【OOP】面向对象

类是面向对象编程的基本单位,它是对象的模板或蓝图。类定义了对象的属性(数据)和行为(方法)。步骤声明一个类,并定义其属性和方法。属性通常是类的成员变量,方法是类的行为。// 属性// 构造函数// 方法定义类:通过定义类来组织代码,将相关的属性和方法封装在一起。创建对象:通过类创建对象,使用对象调用方法和访问属性。应用封装:使用访问修饰符和getter/setter方法来保护类的属性。实现继承:通过继承实现代码重用和扩展功能。实现多态:通过方法重写和重载实现灵活的代码设计。

科马的博客 851

Statistics and Machine Learning Toolbox

Statistics and Machine Learning Toolbox(带书签),MATLAB统计学习工具

Devexpress16.2.6破解工具

Devexpress16.2.6破解工具Devexpress16.2.6破解工具Devexpress16.2.6破解工具Devexpress16.2.6破解工具

Java中的OOP:多态性和接口

如何比较Java中的字符串? 日期:21-04-20Java中的OOP:多态性和接口 日期:21-04-19使用Spring Boot和AspectJ实现方法跟踪基础结构 日期:21-04-18SQL SERVER –关系数据库中的枚举 日期:21-04-16用于Spring Boot项目的简单状态机 日期:21-04-16使用ExecutorService进行Java多线程 日期:21-04-15Java代码审查指南 日期:21-04-152021年最佳缺陷跟踪工具 日期:21-04-15

hixiaoyang的博客 207

假人有限元模型

假人模型,车辆碰撞假人有限元模型,适合做乘员安全的研究者利用

java设计模式(部分转载)

23种设计模式部分 oop七大原则 开闭原则:对扩展开放,对修改关闭 里氏替换原则:继承必须确保超类所拥有的性质在子类种仍然成立 依赖倒置原则:要面向接口编程卖不要面对现实编程 单一职责原则:控制类的粒度大小,将对象解耦,提高它的内聚性 接口隔离原则:要为各个类建立他们需要的专用接口 迪米特原则:至于你的直接朋友交谈,不跟“陌生人”说话 合成复用原则:尽量先使用或者聚合等关联关系来实现,其次在考虑使用继承关系来实现 创建型模式 单例模式,工厂模式,抽象工厂模式,建造者模式,原型模式 单例模式 单例模式注意点

qq_44741982的博客 152

Probability and Statistics - 4th edition

Probability and Statistics - 4th edition

Java常用设计模式总结及应用场景分析

原 java常用设计模式总结 2017年11月23日 21:30:54 qq_14827935 阅读数:3284 ...

Xx丶浅时光的博客 3万+

java常用设计模式总结

设计模式详细讲解推荐阅读 :https://refactoringguru.cn/design-patterns/structural-patterns 掌握常用的几种(最起码单例模式、工厂模式),了解其他的设计模式即可,做到手里有粮,心里不慌。首先,掌握每种模式的定义及使用场景。其次,掌握一个形象的例子,简单的过一遍代码。学习设计模式的真正目的:编程时,有意识地面向接口编程,多用封装、继承、组合、多态等OOP思想,而不仅仅是死记几类设计模式。 常用的设计模式分类:创建型(创建一个对象):单例模式、..

Tiger的专栏 202

设计模式之美

https://time.geekbang.org/column/intro/100039001 设计模式学习导读 (3讲)  01 | 为什么说每个程序员都要尽早地学习并掌握设计模式相关知识? 02 | 从哪些维度评判代码质量的好坏?如何具备写出高质量代码的能力? 03 | 面向对象、设计原则、设计模式、编程规范、重构,这五者有何关系? 设计原则与思想:面向对象 (11讲)  ...

github_38596081的博客 4251

JavaSE知识复习笔记04

JavaSE知识复习笔记04 面向对象相关

赞美万机之神 赞美欧姆尼赛亚 1538

第一阶段>>>Java基础进阶 OOP/Reflect/注解/IO流/API核心

第4天必须掌握知识点>>>基础结构以及类型 一、Java中数据类型有几种? 基本类型八种:byte short int long float double char boolean 二、java中常见的语法结构 1.顺序结构从小至下 按照逻辑 运行代码 2.判断结构 其中分为单分支结构以及多分支结构还有嵌套判断结构 >>>单分支结构 备注:如果只有一条判断if() 可以不用写大括号 直接sout输出 If(){ } >&gt...

m0_61402516的博客 360

关于 设计模式 和 设计程序语言 的一些闲话

关于 设计模式 和 设计程序语言 的一些闲话

qq_44925249的博客 185

Java基础04-面向对象

从零开始的Java教程,第四章节面向对象(上),内容包括类与对象,关键字,匿名对象,单例设计模式,代码块等等。

PengXing_Huang的博客 1189

java单词测试,java单词 - 在线打字测试(dazi.kukuw.com)

java单词贡献者:15533470608 类别:英文 时间:2018-08-04 22:32:16 收藏数:20 评分:0返回上页举报此文章请选择举报理由:广告/谣言/欺诈政治敏感色情/违法信息垃圾文章其他收藏到我的文章改错字public static void main class system out print double string char integer scanner scor...

weixin_35723924的博客 607

设计模式之美04-理论一:当谈论面向对象的时候,我们到底在谈论什么?

面向对象编程的英文缩写是OOP,全称是Object Oriented Programming。对应地,面向对象编程语言的英文缩写是OOPL,全称是Object Oriented Programming Language。面向对象编程中有两个非常重要、非常基础的概念,那就是类(class)和对象(object)。这两个概念最早出现在1960年,在Simula这种编程语言中第一次使用。而面向对象编程这个概念第一次被使用是在Smalltalk这种编程语言中。

fegus的博客 321

21天java_21天Java从入门到精通

简  介本套Java视频无论是您有经验还是零基础,都可以学到更多更多东西,课堂实录,自发布以来,好评如潮!徐培成的Java视频中注重与学生互动,讲授幽默诙谐、细致入微,覆盖Java基础所有核心知识点, 同类Java视频中也是代码量大、案例多、实战性强的。同时,本Java视频教程注重技术原理剖析,深入JDK源码,用实践驱动理论。视频购买咨询请加QQ 2237291613呕心沥血,10年实战经验,徐...

weixin_39683025的博客 587
上一篇: OOP设计模式[JAVA]——03职责链模式
下一篇: 64位Ubuntu下运行某程序时碰到找不到动态库的问题
incanus
博客等级 码龄15年 15粉丝 12原创
评论
成就一亿技术人!
拼手气红包6.0元
还能输入1000个字符
 
 条评论被折叠 查看
添加红包

请填写红包祝福语或标题

个

红包个数最小为10个

元

红包金额最低5元

当前余额3.43元 前往充值 >
需支付:10.00元
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付元
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值