欢迎来到尧图网

客户服务 关于我们

您的位置:首页 > 房产 > 家装 > 命令模式_行为型_GOF23

命令模式_行为型_GOF23

2025/4/2 16:30:39 来源:https://blog.csdn.net/lianghudream/article/details/146636169  浏览:    关键词:命令模式_行为型_GOF23

命令模式

命令模式(Command Pattern)是一种行为型设计模式,核心思想是将请求封装为独立对象,实现请求的发起者与执行者的解耦,并支持请求的队列化、撤销、重做、日志记录等功能。通俗来说,它像餐厅的“订单系统”——顾客(调用者)通过服务员(命令对象)传递订单,厨师(接收者)根据订单烹饪菜品,整个过程无需顾客与厨师直接交互。


一、通俗理解

以智能家居控制为例:

  1. 传统方式:遥控器直接调用电灯的 turnOn() 方法,导致遥控器和电灯强耦合,新增功能需修改遥控器代码。
  2. 命令模式
    • 遥控器(调用者)持有命令对象(如“开灯命令”)。
    • 命令对象封装电灯操作,调用时触发电灯(接收者)的对应方法。
      此时,遥控器无需知道电灯如何实现开关,只需操作命令对象,支持灵活扩展新设备。

二、模式结构

命令模式包含以下角色:

  1. 命令接口(Command):定义执行(execute())和撤销(undo())方法。
  2. 具体命令(ConcreteCommand):绑定接收者与操作(如 LightOnCommand 调用电灯的 turnOn())。
  3. 接收者(Receiver):实际执行操作的对象(如电灯、文件系统)。
  4. 调用者(Invoker):触发命令执行(如遥控器、GUI按钮)。
  5. 客户端(Client):组装命令对象与接收者。

三、适用场景
  1. GUI操作:按钮点击事件、菜单命令。
  2. 事务管理:支持操作回滚(如数据库事务)。
  3. 日志记录:记录命令执行历史用于审计。
  4. 异步任务队列:将命令存入队列延迟执行。

四、代码实现
1. C++ 示例(智能家居控制)
#include <iostream>  
#include <stack>  // 接收者:电灯  
class Light {  
public:  void on() { std::cout << "电灯已开启\n"; }  void off() { std::cout << "电灯已关闭\n"; }  
};  // 命令接口  
class Command {  
public:  virtual void execute() = 0;  virtual void undo() = 0;  virtual ~Command() = default;  
};  // 具体命令:开灯  
class LightOnCommand : public Command {  Light& light;  
public:  LightOnCommand(Light& l) : light(l) {}  void execute() override { light.on(); }  void undo() override { light.off(); }  
};  // 调用者:遥控器  
class RemoteControl {  std::stack<Command*> history;  
public:  void pressButton(Command* cmd) {  cmd->execute();  history.push(cmd);  }  void pressUndo() {  if (!history.empty()) {  history.top()->undo();  history.pop();  }  }  
};  // 客户端  
int main() {  Light light;  LightOnCommand cmd(light);  RemoteControl remote;  remote.pressButton(&cmd);  // 输出:电灯已开启  remote.pressUndo();        // 输出:电灯已关闭  return 0;  
}  
2. Python 示例(文本编辑器撤销功能)
from abc import ABC, abstractmethod  # 命令接口  
class Command(ABC):  @abstractmethod  def execute(self):  pass  @abstractmethod  def undo(self):  pass  # 接收者:文档  
class Document:  def __init__(self):  self.content = ""  def write(self, text):  self.content += text  def erase_last(self):  self.content = self.content[:-1]  # 具体命令:输入文本  
class TextCommand(Command):  def __init__(self, doc, text):  self.doc = doc  self.text = text  def execute(self):  self.doc.write(self.text)  def undo(self):  self.doc.erase_last()  # 调用者:编辑器  
class Editor:  def __init__(self):  self.history = []  def type_text(self, command):  command.execute()  self.history.append(command)  def undo(self):  if self.history:  cmd = self.history.pop()  cmd.undo()  # 客户端  
doc = Document()  
editor = Editor()  
cmd = TextCommand(doc, "Hello")  editor.type_text(cmd)  
print(doc.content)  # 输出:Hello  
editor.undo()  
print(doc.content)  # 输出:Hell  
3. Java 示例(支持宏命令)
import java.util.*;  // 命令接口  
interface Command {  void execute();  void undo();  
}  // 接收者:音响  
class Speaker {  public void playMusic() { System.out.println("播放音乐"); }  public void stopMusic() { System.out.println("停止音乐"); }  
}  // 具体命令:播放音乐  
class PlayCommand implements Command {  private Speaker speaker;  public PlayCommand(Speaker s) { this.speaker = s; }  public void execute() { speaker.playMusic(); }  public void undo() { speaker.stopMusic(); }  
}  // 宏命令(组合多个命令)  
class MacroCommand implements Command {  private List<Command> commands = new ArrayList<>();  public void add(Command cmd) { commands.add(cmd); }  public void execute() {  commands.forEach(Command::execute);  }  public void undo() {  Collections.reverse(commands);  commands.forEach(Command::undo);  }  
}  // 客户端  
public class Client {  public static void main(String[] args) {  Speaker speaker = new Speaker();  MacroCommand macro = new MacroCommand();  macro.add(new PlayCommand(speaker));  macro.add(new PlayCommand(speaker));  macro.execute();  // 输出两次“播放音乐”  macro.undo();      // 输出两次“停止音乐”  }  
}  

五、优缺点分析
优点缺点
1. 解耦调用者与接收者:新增设备无需修改调用者代码1. 类数量增加:每个命令需单独类,可能导致类爆炸
2. 支持撤销/重做:通过历史栈记录操作2. 性能开销:频繁创建命令对象可能影响性能
3. 灵活扩展功能:如日志、队列、事务3. 设计复杂度高:需合理拆分命令粒度

六、总结

命令模式通过封装请求为对象,实现了调用链路的灵活控制,尤其适用于需要动态管理操作历史的场景(如编辑器、智能家居)。其核心价值在于:

  1. 解耦思维:分离请求发起与执行,提升系统扩展性。
  2. 功能增强:通过命令队列、日志、宏命令等扩展功能。
  3. 实际应用:Java的Runnable、Spring的CommandLineRunner均基于此模式。

扩展对比

  • 与策略模式:策略模式关注算法替换,命令模式关注操作封装与生命周期管理。
  • 与观察者模式:观察者模式用于事件通知,命令模式用于操作封装。

版权声明:

本网仅为发布的内容提供存储空间,不对发表、转载的内容提供任何形式的保证。凡本网注明“来源:XXX网络”的作品,均转载自其它媒体,著作权归作者所有,商业转载请联系作者获得授权,非商业转载请注明出处。

我们尊重并感谢每一位作者,均已注明文章来源和作者。如因作品内容、版权或其它问题,请及时与我们联系,联系邮箱:809451989@qq.com,投稿邮箱:809451989@qq.com

热搜词