命令模式(顾客——服务员——烧烤师)
命令模式(Command):
将一个【请求封装】为一个对象,从而使你可用不同的请求对客户进行参数化,对【请求排队】或记录【请求日志】,以及支持【可撤销】的操作。
一、UML结构图
二、示例代码
1 using System; 2 using System.Collections.Generic; 3 using System.Linq; 4 using System.Text; 5 6 namespace 命令模式 7 { 8 class Program 9 { 10 static void Main(string[] args) 11 { 12 //创建 接收请求类 13 Invoke _invoke = new Invoke(); 14 //创建下达命令人 15 Receiver r1 = new Receiver(); 16 Receiver r2 = new Receiver(); 17 18 //r1下达命令 19 Command cmd1 = new ConcreteCommandA(r1); 20 Command cmd2 = new ConcreteCommandB(r1); 21 _invoke.RecevieCommand(cmd1); 22 _invoke.RecevieCommand(cmd2); 23 24 //执行命令 25 _invoke.ExceteCommand(); 26 27 Console.Read(); 28 } 29 } 30 31 /// <summary> 32 /// 下命令的人 33 /// </summary> 34 public class Receiver 35 { 36 public void Action() 37 { 38 Console.WriteLine("我下达的命令,请求执行...."); 39 } 40 } 41 42 /// <summary> 43 /// 命令抽象类(包含两个属性:下命令的对象,执行对象下的命令) 44 /// </summary> 45 public abstract class Command 46 { 47 protected Receiver m_Receiver; 48 public Command(Receiver receive) 49 { 50 m_Receiver = receive; 51 } 52 53 /// <summary> 54 /// 执行命令 55 /// </summary> 56 public virtual void Execute() 57 { 58 m_Receiver.Action(); 59 } 60 } 61 /// <summary> 62 /// 具体命令执行人 63 /// </summary> 64 public class ConcreteCommandA : Command 65 { 66 public ConcreteCommandA(Receiver receive) 67 : base(receive) 68 { 69 70 } 71 public override void Execute() 72 { 73 Console.WriteLine("执行烤鸡翅请求...."); 74 base.Execute(); 75 } 76 } 77 /// <summary> 78 /// 具体命令执行人 79 /// </summary> 80 public class ConcreteCommandB : Command 81 { 82 public ConcreteCommandB(Receiver receive) 83 : base(receive) 84 { 85 86 } 87 public override void Execute() 88 { 89 Console.WriteLine("执行烤羊排请求...."); 90 base.Execute(); 91 } 92 } 93 94 /// <summary> 95 /// 请求类(从命令人处接收请求的命令,然后通知命令执行人执行) 96 /// </summary> 97 public class Invoke 98 { 99 private List<Command> lstCommand = new List<Command>(); 100 /// <summary> 101 /// 接收命令(从下命令人处接收命令) 102 /// </summary> 103 public void RecevieCommand(Command cmd) 104 { 105 if (!lstCommand.Contains(cmd)) 106 { 107 //判断此命令是否能被执行 108 109 //若能执行,就加入命令菜单中 110 lstCommand.Add(cmd); 111 } 112 } 113 114 /// <summary> 115 /// 执行命令 116 /// </summary> 117 public void ExceteCommand() 118 { 119 //执行下达的命令列表,此处可使用队列,逐个是否命令 120 foreach (Command cmd in lstCommand) 121 cmd.Execute(); 122 } 123 } 124 125 126 }
三、作用
1、比较容易设计一个命令队列;
2、在需要情况,可以比较容易的将命令记入日志;
3、允许接收请求的一方,决定是否撤销请求 或者重做。
4、命令类扩展变得容易。
注意:在系统不确定是否使用命令模式时,不要着急使用,因为后续重构也是比较容易的。