Skip to content
Method约 1 分钟0 个小节更新于 2026/06/19在线编辑

命令模式

命令模式把一个请求封装成对象,使请求可以被保存、排队、撤销、重试或记录。

一句话理解:把“要做的事”变成一个对象。

解决什么问题

普通调用是直接执行:

java
service.createOrder();

这种方式简单,但如果你希望支持下面能力,就会不够用:

  • 请求排队执行。
  • 操作日志记录。
  • 失败重试。
  • 撤销和恢复。
  • 延迟执行。
  • 把请求发送到其他线程或消息队列。

命令模式把请求封装为命令对象,让执行时机和执行者解耦。

基本结构

text
Client -> Command -> Receiver
Invoker -> Command.execute()

角色:

  • Command:命令接口。
  • ConcreteCommand:具体命令。
  • Receiver:真正执行业务的人。
  • Invoker:触发命令执行的人。

Java 示例

接收者:

java
class Light {
    void on() {
        System.out.println("light on");
    }

    void off() {
        System.out.println("light off");
    }
}

命令接口:

java
interface Command {
    void execute();
}

具体命令:

java
class LightOnCommand implements Command {
    private final Light light;

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

    public void execute() {
        light.on();
    }
}

class LightOffCommand implements Command {
    private final Light light;

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

    public void execute() {
        light.off();
    }
}

调用者:

java
class RemoteControl {
    private Command command;

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

    public void press() {
        command.execute();
    }
}

使用:

java
Light light = new Light();
RemoteControl remote = new RemoteControl();

remote.setCommand(new LightOnCommand(light));
remote.press();

remote.setCommand(new LightOffCommand(light));
remote.press();

支持撤销

命令对象可以保存撤销逻辑:

java
interface UndoableCommand {
    void execute();

    void undo();
}

例如编辑器中的撤销、重做,本质上就是把用户操作保存成命令历史。

使用场景

  • 任务队列。
  • 异步执行。
  • 操作日志。
  • 撤销/重做。
  • 事务脚本。
  • 菜单按钮和快捷键绑定操作。

优点

  • 请求发起者和执行者解耦。
  • 命令可以排队、记录、重试。
  • 容易扩展新命令。
  • 适合实现撤销和恢复。

缺点

  • 命令类数量可能很多。
  • 简单调用场景会显得繁琐。
  • 如果命令对象设计太大,会变成另一种业务服务。

实战注意

在业务系统里,命令模式常见形态是 CommandCommandHandler、消息任务、定时任务。它的价值不在于名字,而在于把请求封装成可以被调度和管理的对象。

以工程实践沉淀知识,以文档复盘成长。