定義:將一個請求封裝為一個物件,讓你可用不同的請求對客戶進行參數化;對請求排隊或紀錄請求日誌,以及支援可取消的操作。
使用時機: 當需要如取消/恢復操作等功能。
結構圖:來源
假設有一家燒烤店,我們想用程式的方式來實現整個生意的運作方式,比方說客人跟服務生點餐,
並且可以隨時取消,服務生將單子送出,然而負責烤肉的廚師,就會收到單子(命令),並且處理食物。
結構圖:
實現程式碼一:
抽象命令 |
//抽象命令 public abstract class Command { protected Barbecuer receiver; public Command(Barbecuer receiver) { this.receiver = receiver; } //執行命令 abstract public void ExcuteCommand(); } |
具體命令類別 |
烤羊肉串命令 |
//烤羊肉串命令 class BakeMuttonCommand : Command { public BakeMuttonCommand(Barbecuer receiver) : base(receiver) { } public override void ExcuteCommand() { receiver.BakeMutton(); } } |
烤雞翅命令 |
//烤雞翅命令 class BakeChickenWingCommand : Command { public BakeChickenWingCommand(Barbecuer receiver) : base(receiver) { } public override void ExcuteCommand() { receiver.BakeChickenWing(); } } |
服務生類別 |
//服務生 public class Waiter { private Command command; //設置訂單 public void SetOrder(Command command) { this.command = command; } //通知執行 public void Notify() { command.ExcuteCommand(); } } |
用戶端實現 |
class Program { static void Main(string[] args) { //開店前的準備 Barbecuer boy = new Barbecuer(); Command bakeMuttonCommand1 = new BakeMuttonCommand(boy); Command bakeMuttonCommand2 = new BakeMuttonCommand(boy); Command bakeChickenWingCommand1 = new BakeChickenWingCommand(boy); Waiter girl = new Waiter(); //開門營業 girl.SetOrder(bakeMuttonCommand1); girl.Notify(); girl.SetOrder(bakeMuttonCommand2); girl.Notify(); girl.SetOrder(bakeChickenWingCommand1); girl.Notify(); Console.Read(); } } |
- 第一:服務生應該是點完燒烤後,一次性的通知製作,而不是點一樣,服務生就通知廚房做一個。
- 第二:如果有東西沒了,應該是由服務生或烤肉串者來否決這個請求,而不是客戶。
- 第三:客戶點了哪些東西是需要被記錄的,最後結帳可以查詢。
- 第四:客戶隨時可以考慮還沒有製作的肉串。
實現程式碼二:
服務生類別 |
//服務生 public class Waiter { //增加存放具體命令的容器 private IList<Command> orders = new List<Command>(); //設置訂單 public void SetOrder(Command command) { //在客戶提出請求時,對沒貨的收烤進行回絕 if (command.ToString() == "Command.BakeChickenWingCommand") { Console.WriteLine("服務生:雞翅沒有了,請點別的燒烤。"); } else { orders.Add(command); //紀錄客戶所點的燒烤的日誌以備結帳收錢 Console.WriteLine("增加訂單:" + command.ToString() + " 時間:" + DateTime.Now.ToString()); } } //取消訂單 public void CancelOrder(Command command) { orders.Remove(command); Console.WriteLine("取消訂單:" + command.ToString() + " 時間:" + DateTime.Now.ToString()); } //通知全部執行 public void Notify() { foreach (Command cmd in orders) { cmd.ExcuteCommand(); } } } |
用戶端實現 |
class Program { static void Main(string[] args) { //開店前的準備 Barbecuer boy = new Barbecuer(); Command bakeMuttonCommand1 = new BakeMuttonCommand(boy); Command bakeMuttonCommand2 = new BakeMuttonCommand(boy); Command bakeChickenWingCommand1 = new BakeChickenWingCommand(boy); Waiter girl = new Waiter(); //開門營業 顧客點菜 girl.SetOrder(bakeMuttonCommand1); girl.SetOrder(bakeMuttonCommand2); girl.SetOrder(bakeChickenWingCommand1); //點菜完閉,通知廚房 girl.Notify(); Console.Read(); } } |
輸出結果:
最後,命令模式的作用
- 容易設計一個命佇列。
- 在需要的情況下,可以較容易地將命令記入日誌。
- 允許接收請求的一方決定是否要否決請求。
0 Comments:
張貼留言