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


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

    模式图如下

    其核心思路是将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();
            }
        }

     
  • 相关阅读:
    【Demo 0087】线程创建使用消亡
    【Demo 0083】查看进程启动时间
    【Demo 0080】进程
    关于.vhd文件的一个问题
    此服务器上的时间与主域控制器的时间不一致解决方法
    centos5.6下安装mysql5.5.16
    杂谈,入社见闻录
    Oracle 11g学习笔记(1)
    Oracle 11g学习笔记(2)
    转:如何彻底卸载MySQL
  • 原文地址:https://www.cnblogs.com/JoeBlogs/p/8596714.html
Copyright © 2020-2023  润新知