小易说IT 小易说IT

Java 命令模式(Command)示例代码

命令模式:将请求封装成对象,使你可以用不同的请求对客户进行参数化;对请求排队、记录请求日志,以及支持可撤销操作。 角色:

  1. Command(命令接口):声明执行方法 execute(),撤销 undo()

  2. ConcreteCommand(具体命令):持有接收者,实现接口

  3. Receiver(接收者):真正执行业务逻辑

  4. Invoker(调用者 / 请求发起者):持有命令对象,触发命令执行,不关心具体实现

  5. Client(客户端):创建具体命令,绑定接收者

完整示例代码

/**
 * 命令接口 Command
 */
public interface Command {
    // 执行命令
    void execute();
    // 撤销命令
    void undo();
}

/**
 * 接收者 Receiver:灯,真正干活的对象
 */
class Light {
    public void on() {
        System.out.println("✅ 灯打开");
    }
    public void off() {
        System.out.println("❌ 灯关闭");
    }
}

/**
 * 具体命令:开灯命令
 */
class LightOnCommand implements Command {
    private final Light light;

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

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

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

/**
 * 具体命令:关灯命令
 */
class LightOffCommand implements Command {
    private final Light light;

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

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

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

/**
 * 空命令:简化调用者判空逻辑,空对象模式
 */
class NoCommand implements Command {
    @Override
    public void execute() {}
    @Override
    public void undo() {}
}

/**
 * Invoker 调用者:遥控器,持有命令对象,触发执行
 */
class RemoteControl {
    private Command slot;

    public RemoteControl() {
        // 默认赋值空命令,避免null判断
        slot = new NoCommand();
    }

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

    // 按下按钮,执行命令
    public void buttonPressed() {
        slot.execute();
    }

    // 撤销按钮
    public void undoButtonPressed() {
        slot.undo();
    }
}

/**
 * 客户端测试
 */
public class CommandDemo {
    public static void main(String[] args) {
        // 1. 创建接收者
        Light light = new Light();

        // 2. 创建具体命令,绑定接收者
        Command lightOn = new LightOnCommand(light);
        Command lightOff = new LightOffCommand(light);

        // 3. 创建调用者(遥控器)
        RemoteControl remote = new RemoteControl();

        // 设置开灯命令,按下按钮
        remote.setCommand(lightOn);
        remote.buttonPressed();
        remote.undoButtonPressed();

        System.out.println("--------");

        // 设置关灯命令
        remote.setCommand(lightOff);
        remote.buttonPressed();
        remote.undoButtonPressed();
    }
}

输出结果

✅ 灯打开
❌ 灯关闭
--------
❌ 灯关闭
✅ 灯打开

扩展:支持命令队列(批量执行)

import java.util.ArrayList;
import java.util.List;

class MacroCommand implements Command {
    private final List<Command> commandList;

    public MacroCommand(List<Command> commandList) {
        this.commandList = commandList;
    }

    @Override
    public void execute() {
        for (Command cmd : commandList) {
            cmd.execute();
        }
    }

    @Override
    public void undo() {
        // 撤销逆序执行
        for (int i = commandList.size() -1; i >=0; i--) {
            commandList.get(i).undo();
        }
    }
}

// 测试宏命令
class MacroTest {
    public static void main(String[] args) {
        Light light = new Light();
        List<Command> cmds = new ArrayList<>();
        cmds.add(new LightOnCommand(light));
        // 可以追加其他设备命令
        MacroCommand macro = new MacroCommand(cmds);
        macro.execute();
        macro.undo();
    }
}

命令模式要点总结

  1. 解耦:调用者 Invoker 和接收者 Receiver 完全解耦,调用者只操作 Command 接口。

  2. 可撤销 undo:命令对象保存状态,支持回滚。

  3. 宏命令 Macro:把多个命令组合批量执行。

  4. 队列 / 日志:Command 对象可以存入队列、持久化日志,实现任务重放。

  5. 空命令 NoCommand:消除大量 if(null) 判断。

常见业务场景

  • 任务队列、请求排队

  • 操作撤销 / 回滚

  • 菜单按钮、快捷键

  • 日志记录、命令重放

  • 工作流任务封装


本文原创作者:易君召,详见:https://www.yijunzhao.cc/about,转载请注明出处。

原文链接 https://www.yijunzhao.cc/archives/java-command-pattern-example-code

欢迎访问 https://www.yijunzhao.cc/

https://www.yijunzhao.cc/