设计模式之命令模式

文章目录

一、定义

命令模式 (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)功能;
  • 事务处理(批量执行命令,失败时回滚);
  • 任务调度(队列化命令,按顺序执行)。

什么是精神内耗?

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

所谓:

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

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

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

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

相关推荐
易元3 天前
模式组合应用-享元模式
后端·设计模式
vker4 天前
第 2 天:工厂方法模式(Factory Method Pattern)—— 创建型模式
java·后端·设计模式
vker4 天前
第 1 天:单例模式(Singleton Pattern)—— 创建型模式
java·设计模式
晨米酱5 天前
JavaScript 中"对象即函数"设计模式
前端·设计模式
数据智能老司机5 天前
精通 Python 设计模式——分布式系统模式
python·设计模式·架构
数据智能老司机6 天前
精通 Python 设计模式——并发与异步模式
python·设计模式·编程语言
数据智能老司机6 天前
精通 Python 设计模式——测试模式
python·设计模式·架构
数据智能老司机6 天前
精通 Python 设计模式——性能模式
python·设计模式·架构
使一颗心免于哀伤6 天前
《设计模式之禅》笔记摘录 - 21.状态模式
笔记·设计模式
数据智能老司机6 天前
精通 Python 设计模式——创建型设计模式
python·设计模式·架构