设计模式之命令模式

命令模式(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
相关推荐
软考真题app3 小时前
软件设计师考试结构型设计模式考点全解析
设计模式·软件设计师·结构型设计模式·考试考点
xiaolin03338 小时前
【设计模式】- 行为型模式1
设计模式·状态模式·责任链模式·策略模式·命令模式·模板方法模式·行为型模式
沐土Arvin9 小时前
深入理解 requestIdleCallback:浏览器空闲时段的性能优化利器
开发语言·前端·javascript·设计模式·html
bao_lanlan10 小时前
兰亭妙微:用系统化思维重构智能座舱 UI 体验
ui·设计模式·信息可视化·人机交互·交互·ux·外观模式
总是难免11 小时前
设计模式 - 单例模式 - Tips
java·单例模式·设计模式
Java致死16 小时前
设计模式Java
java·开发语言·设计模式
ghost1431 天前
C#学习第23天:面向对象设计模式
开发语言·学习·设计模式·c#
敲代码的 蜡笔小新1 天前
【行为型之迭代器模式】游戏开发实战——Unity高效集合遍历与场景管理的架构精髓
unity·设计模式·c#·迭代器模式
敲代码的 蜡笔小新2 天前
【行为型之命令模式】游戏开发实战——Unity可撤销系统与高级输入管理的架构秘钥
unity·设计模式·架构·命令模式
m0_555762902 天前
D-Pointer(Pimpl)设计模式(指向实现的指针)
设计模式