【设计模式】命令模式

发布于:2025-04-06 ⋅ 阅读:(17) ⋅ 点赞:(0)

简介

假设你有一个智能家居遥控器,上面有多个按钮,每个按钮对应不同的设备操作(如开灯、关灯、调空调温度)。
命令模式的解决方案是:

  1. 将每个操作(如“开灯”)封装成一个独立的命令对象,包含执行和撤销方法。
  2. 遥控器(调用者)不直接控制设备,而是通过触发命令对象来间接操作设备。
  3. 你可以灵活地为按钮更换命令,甚至实现“一键多操作”或“撤销”功能。

适用场景

  1. 需要将请求发送者与接收者解耦(如菜单项触发不同操作)。
  2. 支持请求的排队、撤销/重做、日志记录(如文本编辑器的撤销功能)。
  3. 需要支持宏命令(一键执行多个命令)。

优点

  1. 解耦请求发送者和接收者,增强扩展性。
  2. 支持撤销、重做、事务等复杂操作。

缺点

  1. 每个命令需单独实现类,增加代码量。
  2. 复杂命令可能引入多层嵌套逻辑。

类图

在这里插入图片描述

代码

// 命令接口

interface Command {

    void execute();

    void undo();

}

  

// 接收者:灯

class Light {

    public void on() {

        System.out.println("灯已打开");

    }

    public void off() {

        System.out.println("灯已关闭");

    }

}

  

// 具体命令:开灯

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();

    }

}

  

// 调用者:遥控器按钮

class RemoteControl {

    private Command command;

    public void setCommand(Command command) {

        this.command = command;

    }

    public void pressButton() {

        command.execute();

    }

    public void pressUndo() {

        command.undo();

    }

}

  

// 客户端

public class CommandDemo {

    public static void main(String[] args) {

        Light light = new Light();

        Command lightOn = new LightOnCommand(light);

        RemoteControl remote = new RemoteControl();

        remote.setCommand(lightOn);

        remote.pressButton();   // 执行命令

        remote.pressUndo();    // 撤销命令

    }

}

应用场景

数据库事务中的操作可通过命令模式实现,支持执行与回滚。

import java.util.Stack;


// 事务命令接口

interface TransactionCommand {

    void execute();

    void rollback();

}

  

// 接收者:数据库操作

class Database {

    public void insert(String data) {

        System.out.println("插入数据: " + data);

    }

    public void delete(String data) {

        System.out.println("删除数据: " + data);

    }

}

  

// 具体命令:插入操作

class InsertCommand implements TransactionCommand {

    private Database db;

    private String data;

    public InsertCommand(Database db, String data) {

        this.db = db;

        this.data = data;

    }

    @Override

    public void execute() {

        db.insert(data);

    }

    @Override

    public void rollback() {

        db.delete(data);

    }

}

  

// 事务管理器(支持回滚)

class TransactionManager {

    private Stack<TransactionCommand> history = new Stack<>();

    public void submit(TransactionCommand command) {

        command.execute();

        history.push(command);

    }

    public void rollbackAll() {

        while (!history.isEmpty()) {

            history.pop().rollback();

        }

    }

}

  

// 客户端

public class TransactionDemo {

    public static void main(String[] args) {

        Database db = new Database();

        TransactionManager manager = new TransactionManager();

        manager.submit(new InsertCommand(db, "A"));

        manager.submit(new InsertCommand(db, "B"));

        System.out.println("\n回滚事务:");

        manager.rollbackAll();

    }

}