命令模式案例

wen java案例 2

本文目录导读:

命令模式案例

  1. 智能家居控制系统
  2. 带宏命令的高级应用
  3. 任务队列与日志系统
  4. 使用示例 - 完整场景
  5. 命令模式的优势
  6. 应用场景总结

我来为你提供命令模式的详细案例,包含多个实用场景。

智能家居控制系统

基础类结构

// 1. 命令接口
public interface Command {
    void execute();
    void undo();
}
// 2. 接收者(Receiver)- 各种设备
public class Light {
    private boolean isOn = false;
    public void on() {
        isOn = true;
        System.out.println("电灯已打开");
    }
    public void off() {
        isOn = false;
        System.out.println("电灯已关闭");
    }
}
public class TV {
    private int channel = 1;
    public void turnOn() {
        System.out.println("电视已打开,当前频道:" + channel);
    }
    public void turnOff() {
        System.out.println("电视已关闭");
    }
}

具体命令实现

// 3. 具体命令类
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();
    }
}
// 4. 调用者(Invoker)- 遥控器
public class RemoteControl {
    private Command[] onCommands;
    private Command[] offCommands;
    private Command undoCommand;
    public RemoteControl() {
        onCommands = new Command[7];
        offCommands = new Command[7];
        // 初始化空命令
        for (int i = 0; i < 7; i++) {
            onCommands[i] = new NoCommand();
            offCommands[i] = new NoCommand();
        }
        undoCommand = new NoCommand();
    }
    public void setCommand(int slot, Command onCommand, Command offCommand) {
        onCommands[slot] = onCommand;
        offCommands[slot] = offCommand;
    }
    public void pressOnButton(int slot) {
        onCommands[slot].execute();
        undoCommand = onCommands[slot];
    }
    public void pressOffButton(int slot) {
        offCommands[slot].execute();
        undoCommand = offCommands[slot];
    }
    public void pressUndoButton() {
        undoCommand.undo();
    }
}

带宏命令的高级应用

// 5. 宏命令 - 一键启动家庭影院
public class MacroCommand implements Command {
    private Command[] commands;
    public MacroCommand(Command[] commands) {
        this.commands = commands;
    }
    @Override
    public void execute() {
        for (Command command : commands) {
            command.execute();
        }
    }
    @Override
    public void undo() {
        // 反向撤销
        for (int i = commands.length - 1; i >= 0; i--) {
            commands[i].undo();
        }
    }
}
// 使用示例
public class HomeTheaterTest {
    public static void main(String[] args) {
        // 创建接收者
        Light light = new Light();
        TV tv = new TV();
        Stereo stereo = new Stereo();
        // 创建命令
        Command lightOn = new LightOnCommand(light);
        Command tvOn = new TVOnCommand(tv);
        Command stereoOn = new StereoOnCommand(stereo);
        // 创建宏命令
        Command[] partyOn = {lightOn, tvOn, stereoOn};
        MacroCommand partyMacro = new MacroCommand(partyOn);
        // 设置到遥控器
        RemoteControl remote = new RemoteControl();
        remote.setCommand(0, partyMacro, new NoCommand());
        // 一键启动
        remote.pressOnButton(0);
    }
}

任务队列与日志系统

// 6. 命令队列实现
public class CommandQueue {
    private Queue<Command> queue = new LinkedList<>();
    public void addCommand(Command command) {
        queue.offer(command);
        System.out.println("命令已添加到队列");
    }
    public void processAll() {
        while (!queue.isEmpty()) {
            Command command = queue.poll();
            command.execute();
        }
    }
    public void undoAll() {
        Stack<Command> commandStack = new Stack<>();
        // 记录已执行的命令便于撤销
        while (!queue.isEmpty()) {
            Command command = queue.poll();
            command.execute();
            commandStack.push(command);
        }
        // 撤销所有命令
        while (!commandStack.isEmpty()) {
            commandStack.pop().undo();
        }
    }
}
// 7. 带日志的命令(用于系统恢复)
public class LoggedCommand implements Command {
    private Command command;
    private String logMessage;
    public LoggedCommand(Command command, String logMessage) {
        this.command = command;
        this.logMessage = logMessage;
    }
    @Override
    public void execute() {
        command.execute();
        logCommand();
    }
    @Override
    public void undo() {
        command.undo();
        logCommand("UNDO: " + logMessage);
    }
    private void logCommand() {
        System.out.println("日志记录: " + logMessage);
    }
    private void logCommand(String message) {
        System.out.println("日志记录: " + message);
    }
}

使用示例 - 完整场景

public class CommandPatternDemo {
    public static void main(String[] args) {
        System.out.println("=== 智能家居控制系统 ===");
        // 创建接收者
        Light livingRoomLight = new Light();
        Light kitchenLight = new Light();
        TV livingRoomTV = new TV();
        // 创建命令
        Command livingRoomLightOn = new LightOnCommand(livingRoomLight);
        Command livingRoomLightOff = new LightOffCommand(livingRoomLight);
        Command kitchenLightOn = new LightOnCommand(kitchenLight);
        Command kitchenLightOff = new LightOffCommand(kitchenLight);
        Command tvOn = new TVOnCommand(livingRoomTV);
        Command tvOff = new TVOffCommand(livingRoomTV);
        // 设置遥控器
        RemoteControl remote = new RemoteControl();
        remote.setCommand(0, livingRoomLightOn, livingRoomLightOff);
        remote.setCommand(1, kitchenLightOn, kitchenLightOff);
        remote.setCommand(2, tvOn, tvOff);
        // 操作
        System.out.println("\n--- 操作客厅灯 ---");
        remote.pressOnButton(0);
        remote.pressOffButton(0);
        remote.pressUndoButton(); // 撤销关闭,重新开启
        System.out.println("\n--- 操作电视 ---");
        remote.pressOnButton(2);
        remote.pressOffButton(2);
        // 使用命令队列
        System.out.println("\n--- 命令队列处理 ---");
        CommandQueue queue = new CommandQueue();
        queue.addCommand(new LoggedCommand(livingRoomLightOn, "打开客厅灯"));
        queue.addCommand(new LoggedCommand(tvOn, "打开电视"));
        queue.addCommand(new LoggedCommand(kitchenLightOn, "打开厨房灯"));
        queue.processAll();
    }
}

命令模式的优势

优势 说明 示例
解耦 请求者和执行者完全解耦 遥控器不知道灯的具体实现
可扩展 容易添加新命令 新设备只需实现Command接口
可撤销 支持撤销和重做 undo()方法实现
队列化 命令可以排队执行 宏命令、任务队列
日志化 支持记录所有操作 系统恢复功能

应用场景总结

  • GUI按钮:每个按钮对应一个命令
  • 数据库事务:提交和回滚操作
  • 网络请求:请求的队列化和重试
  • 文本编辑器:撤销/重做功能
  • 游戏开发:玩家操作记录和回放

命令模式通过将请求封装为对象,实现了请求的发送者和接收者之间的完全解耦,使系统更加灵活和可扩展。

抱歉,评论功能暂时关闭!