简介

命令模式(Command Pattern)是一种数据驱动的设计模式,它属于行为型模式。请求以命令的形式包裹在对象中,并传给调用对象。调用对象寻找可以处理该命令的合适的对象,并把该命令传给相应的对象,该对象执行命令。

角色

  • 发起者(Invoker):这是请求的发起者,它知道如何调用命令对象以执行请求。发起者通常不直接执行请求,而是将请求传递给命令对象。

  • 命令(Command):这是命令模式的核心角色。命令对象封装了接收者应该执行的操作。它通常包含一个执行方法,用于在需要时调用接收者的相应方法。

  • 接收者(Receiver):接收者是实际执行请求的对象。它实现了与命令对象相对应的操作。在命令模式中,接收者通常不知道关于命令或发起者的任何信息。

  • 调用者(Caller):调用者是负责创建和调用命令对象的对象。它通常根据某些条件或事件来决定创建和执行命令对象。

  • 客户端(Client):客户端是使用命令模式的用户或程序的一部分。它创建发起者和命令对象之间的连接,并可能根据需要传递参数或配置信息。

优点

  • 解耦发送者和接收者
  • 支持撤销和重做
  • 支持队列和批处理
  • 增强可扩展性
  • 增强可维护性
  • 支持日志和审计

缺点

  • 增加类的数量
  • 增加内存消耗
  • 复杂性提高

应用场景

  • 撤销和重做功能
  • 菜单和工具栏
  • 任务调度
  • 日志记录
  • 批处理
  • 遥控器
  • 数据库事务
  • 网络请求队列
  • 游戏开发

实现

  • 定义命令接口
public interface ICommand
{
    void Execute();
}
  • 实现接口
public class ConcreteCommand : ICommand
{
    private readonly Receiver _receiver;
 
    public ConcreteCommand(Receiver receiver)
    {
        _receiver = receiver;
    }
 
    public void Execute()
    {
        _receiver.ActionToPerform(); // 调用接收者的具体操作方法
    }
}
  • 接收者
public class Receiver
{
    public void ActionToPerform()
    {
        // 这里是接收者要执行的具体操作逻辑
        Console.WriteLine("Receiver's action performed.");
    }
}
  • 调用者
public class Invoker
{
    private ICommand _command;
 
    public void SetCommand(ICommand command)
    {
        _command = command;
    }
 
    public void ExecuteCommand()
    {
        _command?.Execute(); // 安全地执行命令,如果命令为null则不执行任何操作。
    }
}
  • 上层应用调用
class Program
{
    static void Main(string[] args)
    {
        // 创建接收者实例(被请求的对象)
        var receiver = new Receiver(); 
        // 创建具体命令实例,并将接收者传入作为依赖。 
        var command = new ConcreteCommand(receiver); 
        // 创建调用者实例,并将命令设置给它。 
        var invoker = new Invoker(); 
        invoker.SetCommand(command); 
        // 通过调用者执行命令。 实际上会调用接收者的ActionToPerform方法。 
        invoker.ExecuteCommand(); // 这将触发命令的执行,从而调用接收者的操作。 输出 "Receiver's action performed." 到控制台。 
    }
}

在这个案例中,ConcreteCommand 是具体命令类,它知道如何根据接收者的状态来执行操作。Invoker 是调用者,它持有对命令的引用并负责在适当的时候执行这个命令。Receiver 是接收命令的对象,它包含了执行具体操作的逻辑。通过这种方式,你可以灵活地添加新的命令和接收者,而调用者的代码不需要改变。这就是命令模式的基本实现。

04-16 07:42