设计模式之命令模式

文章目录

一、定义

命令模式 (Command Pattern)是一种行为型设计模式,其核心思想是将请求(操作)封装为一个独立的对象,使得可以用不同的请求参数化其他对象、队列化请求、记录请求日志,以及支持可撤销的操作。

核心解决的问题

在软件设计中,经常需要将 "发出命令的对象" 和 "执行命令的对象" 解耦。例如:

  • 遥控器(发出命令)不需要知道电视(执行命令)的具体工作原理,只需按下按钮即可;
  • 文本编辑器的 "撤销" 功能,需要记录历史操作并反向执行。

命令模式通过将 "命令" 封装为对象,让这两者彻底分离,同时支持更灵活的扩展。

二、命令模式的核心角色

命令模式包含 5 个关键角色,它们协同工作完成命令的封装与执行:

  1. 命令接口(Command)
    声明一个执行操作的抽象方法(通常是 Execute()),所有具体命令都需实现该接口。
  2. 具体命令(ConcreteCommand)
    实现命令接口,内部持有一个 "接收者" 对象,并重写 Execute() 方法 ------调用接收者的具体操作来完成命令。
  3. 接收者(Receiver)
    实际执行命令的对象,包含具体的业务逻辑(例如 "开灯""关闭文件" 等操作)。
  4. 调用者(Invoker)
    持有命令对象,负责触发命令的执行(例如按钮、遥控器等)。它不关心命令的具体实现,只需调用命令的 Execute() 方法。
  5. 客户端(Client)
    创建具体命令对象,并将其与接收者关联,然后将命令对象交给调用者。

三、工作流程(以 "遥控器控制灯" 为例)

  1. 客户端创建 "开灯命令"(ConcreteCommand),并将其与 "灯"(Receiver)绑定;
  2. 调用者(遥控器的按钮)持有这个 "开灯命令";
  3. 当用户按下按钮(调用者触发命令),按钮调用命令的 Execute() 方法;
  4. "开灯命令" 的 Execute() 方法调用 "灯" 的 TurnOn() 方法(接收者实际执行操作)。

四、代码示例

java 复制代码
// 1. 命令接口
public interface Command {
    void execute();
}

// 2. 接收者(灯)
public class Light {
    public void turnOn() {
        System.out.println("灯打开了");
    }
    
    public void turnOff() {
        System.out.println("灯关闭了");
    }
}

// 3. 具体命令(关灯命令)
public class TurnOffLightCommand implements Command {
    private Light light; // 持有接收者引用
    
    // 构造方法绑定接收者
    public TurnOffLightCommand(Light light) {
        this.light = light;
    }
    
    @Override
    public void execute() {
        light.turnOff(); // 调用接收者的具体操作
    }
}

// 3. 具体命令(开灯命令)
public class TurnOnLightCommand implements Command {
    private Light light; // 持有接收者引用
    
    // 构造方法绑定接收者
    public TurnOnLightCommand(Light light) {
        this.light = light;
    }
    
    @Override
    public void execute() {
        light.turnOn(); // 调用接收者的具体操作
    }
}

// 4. 调用者(遥控器)
public class RemoteControl {
    private Command command; // 持有命令对象
    
    // 设置命令
    public void setCommand(Command command) {
        this.command = command;
    }
    
    // 触发命令执行(按下按钮)
    public void pressButton() {
        command.execute();
    }
}

// 5. 客户端(测试类)
public class Client {
    public static void main(String[] args) {
        // 创建接收者对象
        Light light = new Light();
        
        // 创建具体命令对象,并绑定接收者
        Command turnOnCommand = new TurnOnLightCommand(light);
        Command turnOffCommand = new TurnOffLightCommand(light);
        
        // 创建调用者(遥控器)
        RemoteControl remote = new RemoteControl();
        
        // 测试开灯命令
        remote.setCommand(turnOnCommand);
        remote.pressButton(); // 输出:灯打开了
        
        // 测试关灯命令
        remote.setCommand(turnOffCommand);
        remote.pressButton(); // 输出:灯关闭了
    }
}

五、命令模式的优点

  1. 解耦:发出命令的调用者与执行命令的接收者完全分离,互不依赖。
  2. 扩展性强:新增命令只需添加新的 ConcreteCommand 类,无需修改现有代码(符合开闭原则)。
  3. 支持复杂操作 :可实现命令队列(批量执行)、日志记录(记录所有操作)、撤销 / 重做(通过反向命令)等功能。
    本人水平有限,有错的地方还请批评指正。

典型应用场景

  • GUI 按钮操作(每个按钮对应一个命令);
  • 文本编辑器的撤销(Undo)/ 重做(Redo)功能;
  • 事务处理(批量执行命令,失败时回滚);
  • 任务调度(队列化命令,按顺序执行)。

什么是精神内耗?

简单地说,就是心理戏太多,自己消耗自己。

所谓:

言未出,结局已演千百遍;

身未动,心中已过万重山;

行未果,假想灾难愁不展;

事已闭,过往仍在脑中演。

相关推荐
无小道1 天前
QT——QFIie和QFileInfo文件类
开发语言·qt·命令模式
J_liaty2 天前
23种设计模式一代理模式
设计模式·代理模式
苏渡苇2 天前
优雅应对异常,从“try-catch堆砌”到“设计驱动”
java·后端·设计模式·学习方法·责任链模式
短剑重铸之日2 天前
《设计模式》第十一篇:总结
java·后端·设计模式·总结
feasibility.2 天前
AI 编程助手进阶指南:从 Claude Code 到 OpenCode 的工程化经验总结
人工智能·经验分享·设计模式·自动化·agi·skills·opencode
BD_Marathon2 天前
七大设计原则介绍
设计模式
YigAin2 天前
Unity23种设计模式之 享元模式
设计模式·享元模式
不绝1912 天前
UGUI相关——基础篇
命令模式
范纹杉想快点毕业2 天前
实战级ZYNQ中断状态机FIFO设计
java·开发语言·驱动开发·设计模式·架构·mfc
茂桑3 天前
DDD领域驱动设计-基础设施层
设计模式·架构