命令模式(Command Pattern)

命令模式(Command pattern),将一个请求封装为一个对象,从而使你可以用不同的请求对客户进行参数化;对请求排队或记录请求日志,以及支持可撤销的操作。
别名
动作(Action),事务(Transcation)

使用性
1)抽象出待执行的动作以参数化某对象。你可用过程语言中的回调(callback)函数表达这种参数化机制。所谓回调函数是指函数先在某处注册,而它将在稍后某个需要的时候被调用。Command模式是回调机制的一个面向对象的替代品。
2)在不同的时刻指定、排列和执行请求;支持取消操作;支持修改日志,这样当系统崩溃时,这些修改可以被重做一遍。
3)用构建在原语操作上的高层操作构造一个系统。这样一种结构在支持事务(transaction)的信息系统中很常见。一个事务封装了对数据的一组变动。Command模式提供了对事务进行建模的方法。Command有一个公共的接口,使得你可以用同一种方式调用所有的事务。同时使用该模式也易于添加新事务以扩展系统。
结构
命令模式(Command Pattern)_第1张图片命令模式(Command Pattern)_第2张图片
参与者
Command
——声明执行操作的接口。
ConcreteCommand
——将一个接收者对象绑定于一个动作。
——调用接收者相应的操作,以实现Execute。
Client
——创建一个具体命令对象并设定它的接收者。
Invoker
——要求该命令执行这个请求。
Receicer
——知道如何实施与执行一个请求相关的操作。任何类都可能作为一个接收者。
协作
Client创建一个ConcreteCommand对象并指定它的Receiver对象。某Invoker对象存储该ConcreteCommand对象。
该Invoker通过调用Command对象的Execute操作来提交一个请求。若该命令是可撤消的,ConcreteCommand就在执行Excute操作之前存储当前状态以用于取消该命令。ConcreteCommand对象对调用它的Receiver的一些操作以执行该请求。
下图展示了这些对象之间的交互。它说明了Command是如何将调用者和接收者(以及它执行的请求)解耦的。
命令模式(Command Pattern)_第3张图片

效果
Command模式有以下效果:
1) Command模式将调用操作的对象与知道如何实现该操作的对象解耦。
2) Command是头等的对象。它们可像其他的对象一样被操纵和扩展。
3) 可将多个命令装配成一个复合命令。一般说来,复合命令是Composite模式的一个实例。
4) 增加新的Command很容易,因为这无需改变已有的类。
实现
1) 一个命令对象应达到何种智能程度;
2) 支持取消(undo)和重做(redo);
3)避免取消操作过程中的错误积累;
4) 使用C++模板。
参考代码
using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;

namespace MyCommand
{
    abstract class Command
    {
        protected Receiver reveiver;

        public Command(Receiver reveiver)
        {
            this.reveiver = reveiver;
        }

        abstract public void Execute();
    }

    class ConcreteCommand : Command
    {
        public ConcreteCommand(Receiver receiver)
            : base(receiver)
        {

        }

        public override void Execute()
        {
            reveiver.Action();
        }
    }

    class Invoker
    {
        private Command command;

        public void SetCommand(Command command)
        {
            this.command = command;
        }

        public void ExcecuteCommand()
        {
            command.Execute();
        }
    }

    class Receiver
    {
        public void Action()
        {
            Console.WriteLine("Execute request!");
        }
    }
}
using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;

namespace MyCommand
{
    class Program
    {
        static void Main(string[] args)
        {
            Invoker i = new Invoker();
            i.SetCommand(new ConcreteCommand(new Receiver()));
            i.ExcecuteCommand();

            Console.ReadKey();
        }
    }
}<span style="font-size:18px;">
</span>

总结
敏捷开发原则告诉我们,不要为代码添加基于猜测的、实际不需要的功能。如果不清楚一个系统是否需要命令
模式,一般就不要捉急去实现它,事实上,在需要的时候通过重构实现这个模式并不困难,只是在真正需要如
撤销/恢复操作等功能时,把原来定的代码重构为命令模式才有意义。

相关模式

状态模式(state pattern)结构

命令模式(Command Pattern)_第4张图片

参考:《设计模式》、《大话设计模式》

你可能感兴趣的:(命令模式(Command Pattern))