今天我們來講一下命令模式。 一、案例 我們去燒烤店吃燒烤,給我們烤羊肉串和雞翅。用簡單的控制台應用程式來模擬一下。 客戶端調用: 二、演繹 1、第一步演繹 如果燒烤店裡有好多人,都要了若幹的烤串和雞翅,那麼,烤肉串者怎麼記得誰點了什麼,點了多少串呢?這樣就會亂掉了。如何解決這個問題呢?我們需要服務員 ...
今天我們來講一下命令模式。
一、案例
我們去燒烤店吃燒烤,給我們烤羊肉串和雞翅。用簡單的控制台應用程式來模擬一下。
1 /// <summary> 2 /// 烤肉串者 3 /// </summary> 4 public class Barbecurer 5 { 6 public void BakeMutton() 7 { 8 Console.WriteLine("烤羊肉串!"); 9 } 10 11 public void BakeChickenWing() 12 { 13 Console.WriteLine("烤雞翅!"); 14 } 15 }
客戶端調用:
1 public static void Main() 2 { 3 Barbecurer boy = new Barbecurer(); 4 boy.BakeMutton(); 5 boy.BakeMutton(); 6 boy.BakeMutton(); 7 boy.BakeChickenWing(); 8 boy.BakeMutton(); 9 boy.BakeMutton(); 10 Console.ReadKey(); 11 }
二、演繹
1、第一步演繹
如果燒烤店裡有好多人,都要了若幹的烤串和雞翅,那麼,烤肉串者怎麼記得誰點了什麼,點了多少串呢?這樣就會亂掉了。如何解決這個問題呢?我們需要服務員,需要菜單,這樣就可以分清了。好,我們來修改一下我們的代碼。
1 /// <summary> 2 /// 烤肉串者 3 /// </summary> 4 public class Barbecurer 5 { 6 public void BakeMutton() 7 { 8 Console.WriteLine("烤羊肉串!"); 9 } 10 11 public void BakeChickenWing() 12 { 13 Console.WriteLine("烤雞翅!"); 14 } 15 } 16 //抽象命令類 17 public abstract class Command 18 { 19 protected Barbecurer receiver; 20 21 public Command(Barbecurer receiver) 22 { 23 this.receiver = receiver; 24 } 25 26 abstract public void ExcuteCommand(); 27 } 28 //烤雞翅命令 29 class BakeChickenWingCommand : Command 30 { 31 public BakeChickenWingCommand(Barbecurer receiver) : base(receiver) 32 { 33 } 34 public override void ExcuteCommand() 35 { 36 receiver.BakeChickenWing(); 37 } 38 } 39 //服務員 40 public class Waiter 41 { 42 private Command command; 43 //服務員類,不用管用戶想要什麼烤肉,反正都是‘命令’,只管記錄訂單,然後通知‘烤肉串者’執行即可 44 public void SetOrder(Command command) 45 { 46 this.command = command; 47 } 48 49 public void Notify() 50 { 51 command.ExcuteCommand(); 52 } 53 }
客戶端調用:
1 public static void Main() 2 { 3 //開店前準備 4 //燒烤店準備好烤肉廚師,服務員,菜單,就等客戶上門 5 Barbecurer boy = new Barbecurer(); 6 Command bakeMuttonCommand1 = new BakeMuttonCommand(boy); 7 Command bakeMuttonCommand2 = new BakeMuttonCommand(boy); 8 Command bakeChickenWingCommand1 = new BakeChickenWingCommand(boy); 9 Waiter girl = new Waiter(); 10 11 //開門營業 12 //服務員根據用戶要求,通知廚房開始製作 13 girl.SetOrder(bakeMuttonCommand1); 14 girl.Notify(); 15 girl.SetOrder(bakeMuttonCommand2); 16 girl.Notify(); 17 girl.SetOrder(bakeChickenWingCommand1); 18 girl.Notify(); 19 Console.ReadKey(); 20 }
2、第二步演繹
在這裡,我們還有幾個問題
①真實情況並不是客戶點一個菜服務員就去通知廚房做一個菜,而是客戶點完之後,服務員再報給廚房製作。
②如果某樣菜沒了,客戶是不知道的,應該由服務員或者廚師來判斷這個菜是否還有。
③客戶點了很多東西,是需要記錄下來的,以便後面結賬使用。
④如果客戶點完菜了,覺得點多了,需要取消幾樣菜。
好,針對上述問題,我們再來修改一下代碼:
我們需要修改一下服務員類
1 //服務員 2 public class Waiter 3 { 4 //增加存放具體命令的容器 5 private IList<Command> orders = new List<Command>(); 6 //設置訂單 7 public void SetOrder(Command command) 8 { 9 if (command.ToString() == "MyTest.BakeChickenWingCommand") 10 { 11 Console.WriteLine("雞翅沒有了,請點別的燒烤"); 12 } 13 else 14 { 15 orders.Add(command); 16 Console.WriteLine($"增加訂單:{command.ToString()},時間:{DateTime.Now}"); 17 } 18 } 19 //取消訂單 20 public void CancelOrder(Command command) 21 { 22 orders.Remove(command); 23 Console.WriteLine($"取消訂單:{command.ToString()},時間:{DateTime.Now}"); 24 } 25 //通知全部執行 26 public void Notity() 27 { 28 //根據用戶點好的訂單通知廚房製作 29 foreach (Command cmd in orders) 30 { 31 cmd.ExcuteCommand(); 32 } 33 } 34 }
客戶端調用:
1 public static void Main() 2 { 3 //開店前準備 4 //燒烤店準備好烤肉廚師,服務員,菜單,就等客戶上門 5 Barbecurer boy = new Barbecurer(); 6 Command bakeMuttonCommand1 = new BakeMuttonCommand(boy); 7 Command bakeMuttonCommand2 = new BakeMuttonCommand(boy); 8 Command bakeChickenWingCommand1 = new BakeChickenWingCommand(boy); 9 Waiter girl = new Waiter(); 10 11 //開門營業 12 //服務員根據用戶要求,通知廚房開始製作 13 girl.SetOrder(bakeMuttonCommand1); 14 girl.SetOrder(bakeMuttonCommand2); 15 girl.SetOrder(bakeChickenWingCommand1); 16 17 //點完菜,通知廚房 18 girl.Notity(); 19 Console.ReadKey(); 20 }
這樣,我們的問題都解決了,以上呢,其實就是用到了命令模式。
好,下麵我們來總結一下命令模式:
命令模式:講一個請求封裝為一個對象,從而使你可用不同的請求對客戶進行參數化對請求排隊或記錄請求日誌,以及支持可撤銷的操作。
來看一下命令模式的基本代碼:
1 /// <summary> 2 /// 聲明執行操作的介面 3 /// </summary> 4 abstract class Command 5 { 6 protected Receiver receiver; 7 8 public Command(Receiver receiver) 9 { 10 this.receiver = receiver; 11 } 12 13 abstract public void Execute(); 14 } 15 /// <summary> 16 /// 具體的命令操作 17 /// </summary> 18 class ConcreteCommand:Command 19 { 20 //將一個接收者對象綁定於這個動作,調用接受者相應的操作,以實現Execute 21 public ConcreteCommand(Receiver receiver) : base(receiver) 22 { 23 } 24 25 public override void Execute() 26 { 27 receiver.Action(); 28 } 29 } 30 //命令的接受者 31 class Receiver 32 { 33 public void Action() 34 { 35 Console.WriteLine("執行請求!"); 36 } 37 } 38 //要求該命令執行這個請求 39 class Invoker 40 { 41 private Command command; 42 43 public void SetCommand(Command command) 44 { 45 this.command = command; 46 } 47 48 public void ExecuteCommand() 49 { 50 command.Execute(); 51 } 52 }
客戶端調用:
1 public static void Main() 2 { 3 Receiver r = new Receiver(); 4 Command c = new ConcreteCommand(r); 5 Invoker i = new Invoker(); 6 i.SetCommand(c); 7 i.ExecuteCommand(); 8 Console.ReadKey(); 9 }
以上就是命令模式的基本代碼。
好了,命令模式今天就講到這裡,下一篇我們講 職責鏈模式
本系列將持續更新,喜歡的小伙伴可以點一下關註和推薦,謝謝大家的支持