1. 程式人生 > 實用技巧 >設計模式 - 20)命令模式

設計模式 - 20)命令模式

/// <summary>
/// 燒烤的人
/// </summary>
class Barbecuer
{
    public void Meat()
    {
        Console.WriteLine("bbq meat");
    }

    public void Vegetable()
    {
        Console.WriteLine("bbq vegetable");
    }
}                                                        

/// <summary>
/// 燒烤命令抽象類
/// </summary>
abstract class Command
{
    protected Barbecuer receiver;

    public Command(Barbecuer boy)
    {
        this.receiver = boy;
    }

    public abstract void ExcuteCommand();
}

/// <summary>
/// 烤肉的命令
/// </summary>
class BarMeatCommand : Command
{
    public BarMeatCommand(Barbecuer boy) : base(boy) { }

    public override void ExcuteCommand()
    {
        receiver.Meat();
    }
}

/// <summary>
/// 烤菜的命令
/// </summary>
class BarVegetableCommand : Command
{
    public BarVegetableCommand(Barbecuer boy) : base(boy) { }

    public override void ExcuteCommand()
    {
        receiver.Vegetable();
    }
}

class Waiter
{
    IList<Command> _command = new List<Command>();

    public void SetOrder(Command command)
    {
        this._command.Add(command);
        Console.WriteLine("增加訂單{0},時間{1}", command.ToString(), DateTime.Now.ToString());
    }

    public void CancelOrder(Command command)
    {
        this._command.Remove(command);
        Console.WriteLine("刪除訂單{0},時間{1}", command.ToString(), DateTime.Now.ToString());
    }

    public void Notify()
    {
        foreach (Command command in _command)
        {
            command.ExcuteCommand();
        }
    }
}

class CommandModelViewModel
{
    public CommandModelViewModel()
    {
        // 燒烤師傅
        Barbecuer boy = new Barbecuer();

        // 服務員
        Waiter waiter = new Waiter();

        Command meatCommand1 = new BarMeatCommand(boy);
        Command meatCommand2 = new BarMeatCommand(boy);
        Command vegetableCommand = new BarVegetableCommand(boy);

        waiter.SetOrder(meatCommand1);
        waiter.SetOrder(meatCommand2);
        waiter.SetOrder(vegetableCommand);

        waiter.Notify();
    }
}

一開始,用緊耦合的方式,就是客戶端直接去呼叫執行命令的接受者,這樣會導致:
1)命令的是否能被執行失去控制;
2)命令的執行未能被記錄;
3)命令的執行未能被撤銷、重做。

而使用命令模式:
執行者有各個方法;
抽象命令類指定執行執行者、抽象執行方法;
某個命令類的執行方法為呼叫執行者的某個方法;
由控制類維護一個命令佇列,並控制命令的執行、記錄。