【设计模式】行为型-命令模式

文章目录


前言

日常开发中,我们常需要对行为进行封装 :比如按钮点击、菜单操作、事务回滚、任务延迟执行、操作记录、撤销/重做等。如果直接调用方法,会造成请求发起者与执行者强耦合 ,无法灵活控制行为。命令模式 正是将请求封装为对象,让你可以像传递对象一样管理、存储、延迟、撤销行为,是实现"操作可记录、可撤销、可排队"的核心行为型模式。


一、概念

命令模式(Command Pattern) 是一种行为型设计模式 ,核心思想:
将一个请求封装为一个对象,从而使你可以用不同的请求对客户进行参数化;对请求排队、记录日志、撤销操作。

简单理解:

  • 把"方法调用"包装成一个对象(Command)
  • 包含:执行、撤销(可选);
  • 发送者只管发出命令,不关心谁执行、怎么执行;
  • 接收者只管执行,不关心谁发来。

一句话:
行为封装成对象,可传、可存、可撤销、可排队。


二、核心结构

  1. Command(抽象命令)
    定义执行、撤销接口。
  2. ConcreteCommand(具体命令)
    绑定接收者,实现执行逻辑。
  3. Receiver(接收者)
    真正执行业务的对象。
  4. Invoker(调用者/发送者)
    持有命令,触发命令。
  5. Client(客户端)
    创建命令、绑定接收者、交给调用者。

三、Java 代码实现(遥控器控制电视)

场景:遥控器按钮 → 控制电视 开/关/换台 ,支持撤销

1. 接收者(真正干活:TV)

java 复制代码
// 接收者:电视机
public class TV {
    public void on() {
        System.out.println("电视已打开");
    }
    public void off() {
        System.out.println("电视已关闭");
    }
    public void changeChannel() {
        System.out.println("切换频道");
    }
}

2. 抽象命令

java 复制代码
public interface Command {
    void execute();  // 执行
    void undo();     // 撤销
}

3. 具体命令:开机

java 复制代码
public class TVOnCommand implements Command {
    private TV tv;
    public TVOnCommand(TV tv) { this.tv = tv; }

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

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

4. 具体命令:关机

java 复制代码
public class TVOffCommand implements Command {
    private TV tv;
    public TVOffCommand(TV tv) { this.tv = tv; }

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

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

5. 调用者(遥控器)

java 复制代码
// 调用者:遥控器
public class RemoteControl {
    private Command command;

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

    // 按下按钮
    public void pressButton() {
        command.execute();
    }

    // 按下撤销
    public void pressUndo() {
        command.undo();
    }
}

6. 客户端使用

java 复制代码
public class Client {
    public static void main(String[] args) {
        TV tv = new TV();

        Command on = new TVOnCommand(tv);
        Command off = new TVOffCommand(tv);

        RemoteControl remote = new RemoteControl();

        // 开机
        remote.setCommand(on);
        remote.pressButton();
        remote.pressUndo(); // 撤销=关机

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

        // 关机
        remote.setCommand(off);
        remote.pressButton();
        remote.pressUndo(); // 撤销=开机
    }
}

输出:

复制代码
电视已打开
电视已关闭
----------
电视已关闭
电视已打开

四、命令模式的超强能力

  1. 队列请求:把命令放入队列,异步/定时执行
  2. 日志请求:记录所有命令,崩溃后重做
  3. 撤销/重做:存储执行栈,回滚操作
  4. 事务性:一组命令统一提交/回滚
  5. 宏命令:一键执行多个命令(组合模式+命令)

五、优缺点

优点

  • 解耦发送者与接收者
  • 易于扩展新命令(符合开闭)
  • 支持撤销、排队、日志、事务
  • 可组合宏命令

缺点

  • 类爆炸:每个行为一个Command类
  • 增加一层间接性,稍复杂

六、应用场景

  • GUI按钮、菜单点击
  • 事务、回滚、重做
  • 延迟执行、异步任务
  • 操作日志、审计
  • 指令集、脚本执行
  • 线程池、任务队列(Runnable 就是命令模式)

经典代表:

  • Java Runnable/Callable
  • Spring ApplicationEvent
  • Git 提交/回滚
  • 编辑器撤销(Ctrl+Z)

七、总结

  1. 命令模式 = 把行为封装成对象
  2. 核心:可执行、可撤销、可存储、可传递
  3. 结构:Command + Receiver + Invoker
  4. 最适合:需要控制、记录、延迟、撤销行为的场景
相关推荐
程序员小寒2 小时前
JavaScript设计模式(六):职责链模式实现与应用
java·javascript·设计模式
无籽西瓜a3 小时前
【西瓜带你学设计模式 | 第五期 - 建造者模式】建造者模式 —— 产品构建实现、优缺点与适用场景及模式区别
java·后端·设计模式·软件工程·建造者模式
木斯佳3 小时前
前端八股文面经大全:字节跳动前端一面·深度解析(Plus Ultra版)(2026-03-30)·面经深度解析
前端·设计模式·八股·光栅化
砍光二叉树4 小时前
【设计模式】行为型-责任链模式
java·设计模式·责任链模式
无籽西瓜a4 小时前
【西瓜带你学设计模式 | 第七期 - 适配器模式】适配器模式 —— 类适配器与对象适配器实现、优缺点与适用场景
java·后端·设计模式·软件工程·适配器模式
BUTCHER55 小时前
二十三种设计模式
设计模式
大数据新鸟6 小时前
设计模式详解-状态模式
ui·设计模式·状态模式
han_6 小时前
JavaScript设计模式(七):迭代器模式实现与应用
前端·javascript·设计模式
大数据新鸟20 小时前
设计模式详解——观察者模式
观察者模式·设计模式