欢迎您访问程序员文章站本站旨在为大家提供分享程序员计算机编程知识!
您现在的位置是: 首页  >  IT编程

面向对象设计模式_命令模式(Command)解读

程序员文章站 2022-03-10 17:39:20
在.Net框架中很多对象的方法中都会有Invoke方法,这种方法的设计实际是用了设计模式的命令模式, 模式图如下 其核心思路是将Client 向Receiver发送的命令行为进行抽象(ICommand),实例化(ConcreteCommand),以便对这些行为能够控制(记录,取消,恢复); 每个Co ......

 在.Net框架中很多对象的方法中都会有Invoke方法,这种方法的设计实际是用了设计模式的命令模式,

模式图如下

面向对象设计模式_命令模式(Command)解读

其核心思路是将Client 向Receiver发送的命令行为进行抽象(ICommand),实例化(ConcreteCommand),以便对这些行为能够控制(记录,取消,恢复);

每个Command与Client是解耦的,即不依赖具体客户,调度者Invoker可以负责记录,控制客户执行了那些请求,与客户端存在单一的关联。

示例:计算器(Calculator)可以执行很多计算操作,客户(client)向指定的接收者发送指令,命令从客户到达接收者实际上是间接进行的,是先通过调度者(Invoker)将指定的输入(state)和指定的命令,传递给接收者,接受者再执行具体的任务。代码如下

//示例:一个计算器,接受用户的计算请求,计算器提供一些计算方法,要求请求任务中过程可以记录请求的行为,请求中状态的变化和请求继续和取消
    public class Client
    {
        public Invoker Invoker { get; set; } = new Invoker();
//简化代码 public void Invoke(string CommandName,params object[] states) { Invoker.Invoke(CommandName, states); }
//简化代码 public void Invoke(string CommandName,out object result,params object[] states) { Invoker.Invoke(CommandName, out result, states); } } public class Invoker { public Dictionary<string, ICommand> Commands { get; set; } = new Dictionary<string, ICommand>(); /// <summary> /// /// </summary> /// <param name="CommandName"></param> /// <param name="returnResult">需要返回结果的命令</param> /// <param name="states"></param> public void Invoke(string CommandName,out object returnResult, params object[] states) { //传递参数 Commands[CommandName].State = states; //执行操作 Commands[CommandName].Execute(); returnResult = Commands[CommandName].State; } /// <summary> /// 无需返回结果 /// </summary> /// <param name="CommandName"></param> /// <param name="states"></param> public void Invoke(string CommandName,params object[] states) { //传递参数 Commands[CommandName].State = states; //执行操作 Commands[CommandName].Execute(); } //下面可以写一些方法用来恢复数据或记录行为 //可以在Invoke 方法中使用异步方法放入token来中断执行,并将State恢复到原来状态 } public interface ICommand { string CommandName { get; set; } object State { get; set; }//记录状态,可以是数据 void Execute(); } //求积运算 public class CalcuteMulCommand : ICommand { public string CommandName { get ; set ; } public object State { get ; set ; } private object receiver; public CalcuteMulCommand(object _receiver) { receiver = _receiver; } public void Execute() { State= ( (Calculator)receiver).Mutiply((int)((object[])State)[0], (int)((object[])State)[1]); } } internal class Calculator { public Calculator() { } public double Mutiply(int a,int b) { return a * b; } }

//测试代码

class Test
    {
        static void Main(string[] args)
        {
           
           
            Client client = new Client();
            client.Invoker.Commands.Add("CalcuteMulCommand", new CalcuteMulCommand(new Calculator()));
            object result;
            client.Invoke("CalcuteMulCommand",out result, 5, 2);


            Console.WriteLine(result.ToString());
            Console.ReadKey();
        }
    }