全部学科
NodeJS全栈
nodejs
Python全栈
python
小程序首页
📅 2026-05-11 6 分钟 ✍️ juanwangdev

Java命令模式

命令模式将请求封装为对象,支持请求排队、撤销、重做。

模式定义

意图:将请求封装为对象,使请求发送者与接收者解耦。

适用场景

  • 需要将请求参数化
  • 需要支持撤销/重做
  • 需要记录请求日志
  • 需要事务操作

模式结构

命令接口

Java
public interface Command {
    void execute();
    void undo();  // 撤销
}

接收者

Java
public class Light {
    public void on() {
        System.out.println("灯打开");
    }

    public void off() {
        System.out.println("灯关闭");
    }
}

具体命令

Java
public class LightOnCommand implements Command {
    private Light light;

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

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

    @Override
    public void undo() {
        light.off();
    }
}

public class LightOffCommand implements Command {
    private Light light;

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

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

    @Override
    public void undo() {
        light.on();
    }
}

调用者

Java
public class RemoteControl {
    private Command command;
    private Command lastCommand;  // 记录最后命令,用于撤销

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

    public void pressButton() {
        command.execute();
        lastCommand = command;
    }

    public void pressUndo() {
        if (lastCommand != null) {
            lastCommand.undo();
        }
    }
}

使用示例

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

remote.setCommand(new LightOnCommand(light));
remote.pressButton();  // 灯打开

remote.setCommand(new LightOffCommand(light));
remote.pressButton();  // 灯关闭

remote.pressUndo();    // 灯打开(撤销关闭)

命令队列

Java
public class CommandQueue {
    private List<Command> commands = new ArrayList<>();

    public void addCommand(Command command) {
        commands.add(command);
    }

    public void executeAll() {
        for (Command command : commands) {
            command.execute();
        }
        commands.clear();
    }
}

宏命令

Java
public class MacroCommand implements Command {
    private List<Command> commands = new ArrayList<>();

    public void addCommand(Command command) {
        commands.add(command);
    }

    @Override
    public void execute() {
        for (Command command : commands) {
            command.execute();
        }
    }

    @Override
    public void undo() {
        for (int i = commands.size() - 1; i >= 0; i--) {
            commands.get(i).undo();
        }
    }
}

// 使用:一键执行多个命令
MacroCommand macro = new MacroCommand();
macro.addCommand(new LightOnCommand(light1));
macro.addCommand(new LightOnCommand(light2));
macro.addCommand(new TVOnCommand(tv));
macro.execute();  // 所有设备打开

撤销重做实现

Java
public class UndoRedoManager {
    private Stack<Command> undoStack = new Stack<>();
    private Stack<Command> redoStack = new Stack<>();

    public void execute(Command command) {
        command.execute();
        undoStack.push(command);
        redoStack.clear();
    }

    public void undo() {
        if (!undoStack.isEmpty()) {
            Command command = undoStack.pop();
            command.undo();
            redoStack.push(command);
        }
    }

    public void redo() {
        if (!redoStack.isEmpty()) {
            Command command = redoStack.pop();
            command.execute();
            undoStack.push(command);
        }
    }
}

实际应用示例

文本编辑器

Java
public interface TextCommand {
    void execute();
    void undo();
}

public class InsertCommand implements TextCommand {
    private StringBuilder text;
    private String inserted;
    private int position;

    public InsertCommand(StringBuilder text, String inserted, int position) {
        this.text = text;
        this.inserted = inserted;
        this.position = position;
    }

    @Override
    public void execute() {
        text.insert(position, inserted);
    }

    @Override
    public void undo() {
        text.delete(position, position + inserted.length());
    }
}

// 使用
StringBuilder text = new StringBuilder("Hello");
UndoRedoManager manager = new UndoRedoManager();

manager.execute(new InsertCommand(text, " World", 5));
System.out.println(text);  // "Hello World"

manager.undo();
System.out.println(text);  // "Hello"

命令模式优点

  1. 解耦请求发送者与执行者
  2. 支持撤销/重做
  3. 支持命令排队和日志
  4. 新增命令不影响现有代码

注意事项

命令类数量可能很多

撤销需记录足够状态信息

命令应尽量轻量,避免复杂逻辑

GUI按钮、菜单项操作是典型应用

要点总结

  1. 命令模式将请求封装为对象,解耦调用者与接收者
  2. Command接口定义execute()和undo()
  3. Invoker持有命令对象,负责调用
  4. 支持撤销重做、命令队列、宏命令
  5. GUI操作、事务处理是典型应用场景

📝 发现内容有误?点击此处直接编辑

← 上一篇 Java原型模式
下一篇 → Java备忘录模式
想查看更多题目和详细解析?
小程序提供完整的题库、模拟考试和详细解析
马上就来

长按或扫描二维码,立即体验

扫码体验小程序
马上就来
使用微信扫描二维码
立即体验完整题库