在.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();
}
}