设计模式之命令模式

命令模式(Command)

定义

将**请求(一个动作)**封装成对象(命令对象),使得可以用不同的请求对客户进行参数化。

在命令模式中,"请求"指的是一个特定的操作或动作,即客户端希望调用的功能。这个请求被封装在一个对象中,即命令对象。命令对象包含了执行该请求所需的所有信息,包括调用哪个对象、执行什么方法以及可能需要的参数等。

使用场景

主要角色

  1. 命令(Command): 命令是一个接口或抽象类,其中定义了执行特定操作的方法。它通常包含一个 execute 方法,该方法在调用时会触发与命令相关的操作。命令的实现类将具体的操作绑定到 execute 方法中。
  2. 具体命令(ConcreteCommand): 具体命令是命令接口的实现类。它关联了一个接收者对象,并实现了 execute 方法,该方法调用接收者的具体操作来完成命令请求。
  3. 调用者(Invoker): 调用者是负责触发命令执行的对象。它包含一个命令对象,并在某个时刻调用命令的 execute 方法。调用者并不需要了解命令的具体细节,只需知道如何调用命令。
  4. 接收者(Receiver): 接收者是实际执行命令操作的对象。它知道如何执行具体的操作。命令对象通过调用接收者的方法来实现命令的具体执行。
  5. 客户端(Client): 客户端是创建和配置命令对象、具体命令对象、调用者以及接收者的地方。客户端负责组装这些对象来创建一个完整的命令模式。

类图

示例代码

java 复制代码
/**
 * 接收者
 */
public class Light {
    void turnOn() {
        System.out.println("Light is ON");
    }

    void turnOff() {
        System.out.println("Light is OFF");
    }
}
java 复制代码
public interface Command {
    void execute();
    void undo();
}
java 复制代码
/**
 * 具体命令 开灯
 */
public class LightOnCommand implements Command {
    private Light light;

    LightOnCommand(Light light) {
        this.light = light;
    }

    @Override
    public void execute() {
        light.turnOn();
    }

    @Override
    public void undo() {
        light.turnOff();
    }
}
java 复制代码
/**
 * 具体命令:关灯
 */
public class LightOffCommand implements Command {
    private Light light;

    LightOffCommand(Light light) {
        this.light = light;
    }

    @Override
    public void execute() {
        light.turnOff();
    }

    @Override
    public void undo() {
        light.turnOn();
    }
}
java 复制代码
/**
 * 调用者 遥控器
 */
public class RemoteControl {
    private Command command;
    private List<Command> commandHistory = new ArrayList<>();

    void setCommand(Command command) {
        this.command = command;
        commandHistory.add(command);
    }

    void pressButton() {
        command.execute();
        commandHistory.add(command);
    }
}

总结

命令模式在调用者和具体的执行者(接受者)之间加了一层(命令层)

优点

  1. 解耦调用者和接收者: 命令模式将请求封装成独立的对象,使得调用者不需要直接知道接收者的细节。这种解耦可以降低系统中各个模块之间的依赖关系,提高代码的可维护性。
  2. 支持撤销和重做: 命令模式通过保存命令对象的历史状态,提供了简单的撤销和重做机制。这对于需要支持撤销和重做操作的应用程序是一个很有用的特性。
  3. 支持事务: 如果命令对象能够包含多个原子操作,那么命令模式可以用于实现事务处理系统。当命令对象被执行时,它们可以一起成功或一起失败。
  4. 可扩展性: 命令模式允许您轻松添加新的命令类,而无需更改现有的调用者和接收者。这使得系统更加灵活,容易扩展。
  5. 统一的接口: 命令模式为所有命令提供了统一的接口,这使得调用者无需关心具体的命令类。这种一致性的接口使得系统更易于理解和维护。
  6. 易与实现宏命令和组合命令

缺点

  1. 复杂度
  2. 性能开销

工作中遇到场景

  1. 文本编辑器(撤销undo与重做redo)
  2. 图形编辑器(撤销undo与重做redo)
    我的博客即将同步至腾讯云开发者社区,邀请大家一同入驻:https://cloud.tencent.com/developer/support-plan?invite_code=2klwrba6wi4g4
相关推荐
刷帅耍帅18 分钟前
设计模式-桥接模式
设计模式·桥接模式
MinBadGuy1 小时前
【GeekBand】C++设计模式笔记5_Observer_观察者模式
c++·设计模式
刷帅耍帅2 小时前
设计模式-生成器模式/建造者模式Builder
设计模式·建造者模式
蜡笔小新..1 天前
【设计模式】软件设计原则——开闭原则&里氏替换&单一职责
java·设计模式·开闭原则·单一职责原则
性感博主在线瞎搞1 天前
【面向对象】设计模式概念和分类
设计模式·面向对象·中级软件设计师·设计方法
lucifer3111 天前
JavaScript 中的组合模式(十)
javascript·设计模式
lucifer3111 天前
JavaScript 中的装饰器模式(十一)
javascript·设计模式
蜡笔小新..1 天前
【设计模式】软件设计原则——依赖倒置&合成复用
设计模式·依赖倒置原则·合成复用原则
刷帅耍帅1 天前
设计模式-代理模式
设计模式·代理模式
神的孩子都在歌唱1 天前
行为设计模式 -观察者模式- JAVA
java·观察者模式·设计模式