设计模式之命令模式

命令模式(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
相关推荐
晨米酱11 小时前
JavaScript 中"对象即函数"设计模式
前端·设计模式
数据智能老司机16 小时前
精通 Python 设计模式——分布式系统模式
python·设计模式·架构
数据智能老司机17 小时前
精通 Python 设计模式——并发与异步模式
python·设计模式·编程语言
数据智能老司机17 小时前
精通 Python 设计模式——测试模式
python·设计模式·架构
数据智能老司机17 小时前
精通 Python 设计模式——性能模式
python·设计模式·架构
使一颗心免于哀伤17 小时前
《设计模式之禅》笔记摘录 - 21.状态模式
笔记·设计模式
数据智能老司机2 天前
精通 Python 设计模式——创建型设计模式
python·设计模式·架构
数据智能老司机2 天前
精通 Python 设计模式——SOLID 原则
python·设计模式·架构
烛阴2 天前
【TS 设计模式完全指南】懒加载、缓存与权限控制:代理模式在 TypeScript 中的三大妙用
javascript·设计模式·typescript
李广坤2 天前
工厂模式
设计模式