设计模式之命令模式

命令模式(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
相关推荐
思忖小下10 小时前
梳理你的思路(从OOP到架构设计)_简介设计模式
设计模式·架构·eit
liyinuo201712 小时前
嵌入式(单片机方向)面试题总结
嵌入式硬件·设计模式·面试·设计规范
aaasssdddd9614 小时前
C++的封装(十四):《设计模式》这本书
数据结构·c++·设计模式
T1an-114 小时前
设计模式之【观察者模式】
观察者模式·设计模式
思忖小下16 小时前
梳理你的思路(从OOP到架构设计)_设计模式Factory Method模式
设计模式·工厂方法模式·eit
霁月风17 小时前
设计模式——工厂方法模式
c++·设计模式·工厂方法模式
发飙的蜗牛'19 小时前
23种设计模式
android·java·设计模式
NorthCastle1 天前
设计模式-创建型模式-简单工厂模式详解
设计模式·简单工厂模式
越甲八千1 天前
重拾设计模式-外观模式和适配器模式的异同
设计模式·适配器模式·外观模式
越甲八千1 天前
重拾设计模式--适配器模式
设计模式·适配器模式