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

文章目录


前言

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


一、概念

命令模式(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. 最适合:需要控制、记录、延迟、撤销行为的场景
相关推荐
CPUOS201019 小时前
嵌入式C语言高级编程之MVC设计模式
c语言·设计模式·mvc
张涛酱1074561 天前
Subagent Orchestration 深入解析:多Agent协作的层级架构
spring·设计模式·ai编程
小江的记录本1 天前
【系统设计】《2026高频经典系统设计题》(秒杀系统、短链接系统、订单系统、支付系统、IM系统、RAG系统设计)(完整版)
java·后端·python·安全·设计模式·架构·系统架构
楼田莉子1 天前
同步/异步日志系统:日志器管理器模块\全局接口\性能测试
linux·服务器·开发语言·c++·后端·设计模式
Meya11271 天前
U位资产管理系统:数据中心“最后一公里“的精细化治理
设计模式·开源·交互
回忆2012初秋2 天前
工厂方法模式完整实现:GPS转换
设计模式·工厂方法模式
其实防守也摸鱼2 天前
无线网络安全---WLAN相关安全工具--kali(理论附题目)
linux·安全·web安全·学习笔记·kali·命令模式·wlan
胡志辉的博客2 天前
多智能体协作,不是多开几个 Agent:从中介者模式看 OpenClaw 和 Hermes Agent
人工智能·设计模式·ai·agent·中介者模式·openclaw·herman
shark22222222 天前
能懂!基于Springboot的用户增删查改(三层设计模式)
spring boot·后端·设计模式
014-code2 天前
日志规范:怎么写才不算写废话
java·开发语言·设计模式·日志