定義:將一個請求封裝為一個物件,讓你可用不同的請求對客戶進行參數化;對請求排隊或紀錄請求日誌,以及支援可取消的操作。
使用時機: 當需要如取消/恢復操作等功能。
結構圖:來源
假設有一家燒烤店,我們想用程式的方式來實現整個生意的運作方式,比方說客人跟服務生點餐,
並且可以隨時取消,服務生將單子送出,然而負責烤肉的廚師,就會收到單子(命令),並且處理食物。
結構圖:
實現程式碼一:
| 抽象命令 |
//抽象命令
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:
張貼留言