zoukankan      html  css  js  c++  java
  • 设计模式---命令模式

    前言

    好久没有发博了,最近生活上发生了不小的变化,我亲爱的宝宝降临人间,自己也是喜当爹。做爹了之后,就要做一些做爹的该做的事情,照顾宝宝、家务活那都是少不了,学习的时间自然是减少了。当然自己并没有停止学习的脚步,这段时间也有看Pluralsight的课,重温ASP.NET Security、企业架构设计、EF和WCF相关的东西,不过,总归都是零零碎碎,毕竟生活忙起来之后,留下学习的时间一般都比较碎片化。写博客本身更加需要大块的时间去思考去总结,所以博客量就下降了。不过呢,习惯总是要坚持下去,就算再忙,一个月至少一篇吧

    正题

    回到正题,本篇说一下设计模式之命令模式,我们来看官方解释:

    一组行为抽象为对象实现二者之间的松耦合。这就是命令模式(Command Pattern)

    再来看一下外文社区的解释:

    Encapsulate a request as an object, thereby letting you parameterize clients with different requests, queue or log requests, and support undoable operations

    将请求封装为一个对象,从而让你根据不同的请求、队列或者日志请求参数化客户调用,并且支持撤销操作

    个人比较喜欢后者的解释

    UML类图

    参与者

    • Command,命令接口
    • ConcreteCommand,具体命令实现对象,虚实现,通常持有接收者,并调用接收者的功能来完成命令要执行的操作
      • 绑定接收者和Action行为
      • 通过调用Receiver上对应的操作来实现命令接口
    • Client,创建具体的命令对象,并且设置命令对象的接收者,注意这个不是我们常规意义上的客户端,而是在组装命令对象和接收者,或许,把这个Client称为装配者会更好理解,因为真正使用命令的客户端是从Invoker来触发执行
    • Invoker,要求命令对象执行请求,通常会持有命令对象,可以持有很多的命令对象。这个是客户端真正触发命令并要求命令执行相应操作的地方,也就是说相当于使用命令对象的入口
    • Receiver,接收者,真正执行命令的对象。任何类都可能成为一个接收者,只要它能够实现命令要求实现的相应功能

    代码实现

    • 命令接口
    namespace Command
    {
        abstract class Command
        {
            protected Receiver receiver;
    
            // Constructor
            public Command(Receiver receiver)
            {
                this.receiver = receiver;
            }
    
            public abstract void Execute();
        }
    }
    • 接收者
    namespace Command
    {
        /// <summary>
        /// The 'Receiver' class
        /// </summary>
        class Receiver
        {
            public void Action()
            {
                Console.WriteLine("Called Receiver.Action()");
            }
        }
    }
    • 具体命令
    namespace Command
    {
        class ConcreteCommand : Command
        {
            // Constructor
            public ConcreteCommand(Receiver receiver) :
                base(receiver)
            {
            }
    
            public override void Execute()
            {
                receiver.Action();
            }
        }
    }
    • Invoker命令调用入口
    namespace Command
    {
        /// <summary>
        /// The 'Invoker' class
        /// </summary>
        class Invoker
        {
            private Command _command;
    
            public void SetCommand(Command command)
            {
                this._command = command;
            }
    
            public void ExecuteCommand()
            {
                _command.Execute();
            }
        }
    }
    • Client装配执行
    namespace Command
    {
        class Program
        {
            static void Main(string[] args)
            {
                // Create receiver, command, and invoker
                Receiver receiver = new Receiver();
                Command command = new ConcreteCommand(receiver);
                Invoker invoker = new Invoker();
    
                // Set and execute command
                invoker.SetCommand(command);
                invoker.ExecuteCommand();
    
                // Wait for user
                Console.ReadKey();
            }
        }
    }

    结语

    说实话,到目前为止在实际工作中并没有使用到此模式,倒是有看到别人用到过。将请求和实现进行解耦,在一些大型分布式系统中,确实具备它的优势。比如将单向异步的请求消息封装成命令,使用分布式消息组件进行通讯和处理,比如DB的一些CUD操作等等,可以统一编程模型,方便维护和管理

  • 相关阅读:
    singleTon 模式
    最近的工作经验
    sql server里的快捷键
    Bridge 模式
    [转]在.NET客户端程序中使用多线程
    wse
    关于高频查询界面
    判断字段值已经存在
    获取当前供应商的联系人信息
    获取系统常量
  • 原文地址:https://www.cnblogs.com/fecktty2013/p/designpatterns-command.html
Copyright © 2011-2022 走看看