行为型设计模式——命令模式
将一个请求封装为一个对象,使得调用者(发起请求)与接收者(执行请求)完全解耦,从而使得可以用不同的请求对客户进行参数化:对请求排队或记录请求日志,以及支持可撤销的操作。
适用于
①抽象出待执行的动作以参数化某对象。Command模式是过程语言中的回调机制的一个面向对象的替代品。
②在不同的时刻指定,排队和执行请求。一个Command对象可以有一个与初始请求无关的生命周期。如果一个请求的接收者可用一种与地址空间无关的方式表达,那么就可以将负责该请求的命令对象传递给另一个不同的进程并在那儿实现该请求。
③支持取消操作。Command的Execute操作可在实施操作前将状态存储起来,再取消操作时这个状态用来消除该操作的影响。Command接口必须添加一个Unexecute操作,该操作取消上一次Execute调用的效果。执行的命令被存储在一个历史列表中。可通过向后和向前遍历这一列表并分别调用Unexecute和Execute来实现重数不限的“取消”和“重做”。
④支持修改日志。这样当系统崩溃时,这些修改可以被重做一次。在Command接口中添加装载操作和存储操作,可以用来保持变动的一个一致的修改日志。从崩溃中恢复的调用过程包括从磁盘中重新读入记录下来的命令并用Execute操作重新执行它们。
⑤用构建在原语操作上的高层操作构造一个系统。这样一种结构在支持事务的信息系统中很常见。Command模式提供了对事物进行建模的方法。Command有一个公共接口,使得可以用同一种方式调用所有的事务,同时使用该模式也是易于添加新事务以扩展系统。
类图如下

1 internal class Program 2 { 3 static void Main(string[] args) 4 { 5 //创建订单对象 6 Order order1 = new Order(); 7 order1.SetDiningTable(1); 8 9 order1.setFood("蛋炒饭", 1); 10 order1.setFood("双皮奶", 1); 11 12 Order order2 = new Order(); 13 order2.SetDiningTable(2); 14 15 order2.setFood("凉面", 1); 16 order2.setFood("可乐小杯", 1); 17 18 //创建厨师,接收者 19 SeniorChef seniorChef = new SeniorChef(); 20 21 //创建命令对象 22 OrderCommand cmd1 = new OrderCommand(seniorChef, order1); 23 OrderCommand cmd2 = new OrderCommand(seniorChef, order2); 24 25 //创建服务员,请求者 26 Waitor waitor = new Waitor(); 27 waitor.SetCommand(cmd1); 28 waitor.SetCommand(cmd2); 29 30 //让请求者发起命令 31 waitor.OrderUP(); 32 } 33 }
1 /// <summary> 2 /// 抽象命令类 3 /// </summary> 4 internal interface ICommand 5 { 6 //执行命令 7 void Execute(); 8 }
1 /// <summary> 2 /// 具体命令类 3 /// </summary> 4 internal class OrderCommand : ICommand 5 { 6 //持有具体接收者对象 7 private SeniorChef seniorChef; 8 private Order order; 9 10 public OrderCommand(SeniorChef seniorChef, Order order) 11 { 12 this.order = order; 13 this.seniorChef = seniorChef; 14 } 15 public void Execute() 16 { 17 Console.WriteLine(order.GetDiningTable() + "桌的订单"); 18 Dictionary<string, int> foodDir = order.GetDoofDir(); 19 foreach (var foodName in foodDir.Keys) 20 { 21 seniorChef.MakeFood(foodName, foodDir[foodName]); 22 } 23 Console.WriteLine(order.GetDiningTable() + "桌的订单好了"); 24 } 25 }
1 /// <summary> 2 /// 订单类,辅助类 3 /// </summary> 4 internal class Order 5 { 6 //餐桌号码 7 private int diningTable; 8 9 //所下单的餐品及份数 10 private Dictionary<string, int> doofDir = new Dictionary<string, int>(); 11 12 public int GetDiningTable() 13 { 14 return diningTable; 15 } 16 17 public void SetDiningTable(int no) 18 { 19 diningTable = no; 20 } 21 22 public Dictionary<string, int> GetDoofDir() 23 { 24 return doofDir; 25 } 26 27 public void setFood(string name, int num) 28 { 29 doofDir[name] = num; 30 } 31 }
1 /// <summary> 2 /// 厨师类,接收者类 3 /// </summary> 4 internal class SeniorChef 5 { 6 /// <summary> 7 /// 做餐方法 8 /// </summary> 9 /// <param name="name"></param> 10 /// <param name="num"></param> 11 public void MakeFood(string name, int num) 12 { 13 Console.WriteLine(num + "份" + name); 14 } 15 }
1 /// <summary> 2 /// 服务员类,请求者类 3 /// </summary> 4 internal class Waitor 5 { 6 //持有多个命令对象 7 private List<ICommand> commands = new List<ICommand>(); 8 9 public void SetCommand(ICommand command) 10 { 11 commands.Add(command); 12 } 13 14 //发起命令功能 15 public void OrderUP() 16 { 17 Console.WriteLine("美女服务员:大厨,新订单来了。。。。"); 18 foreach (ICommand command in commands) 19 { 20 if (command != null) 21 { 22 command.Execute(); 23 } 24 } 25 } 26 27 }

浙公网安备 33010602011771号