一. 简述
将一个请求封装为一个对象,从而使你可用不同的请求对客户进行参数化;对请求排队或记录请求日志,以及支持可撤销的操作。
属于行为型模式。
二. 组成
三. UML类图
四. 基本代码
using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
namespace CommandExample
{
/*烤肉串者类*/
public class Barbecuer
{
//烤羊肉
public void BakeMutton()
{
Console.WriteLine("烤羊肉串...");
}
//烤鸡翅
public void BackChickenWing()
{
Console.WriteLine("烤鸡翅...");
}
}
/*抽象命令*/
public abstract class Command
{
protected Barbecuer receiver;
public Command(Barbecuer receiver)//抽象命令类,只需要确定“烤肉串者”是谁
{
this.receiver = receiver;
}
//执行命令
public abstract void ExcuteCommand();
}
/*具体命令类,烤羊肉串命令*/
class BakeMuttonCommand : Command
{
public BakeMuttonCommand(Barbecuer receiver) : base(receiver)
{}
public override void ExcuteCommand()
{
receiver.BakeMutton();
}
}
/*烤鸡翅命令*/
class BackChickenWingCommand : Command
{
public BackChickenWingCommand(Barbecuer receiver)
: base(receiver)
{ }
public override void ExcuteCommand()
{
this.receiver.BackChickenWing();
}
}
/*服务员*/
public class Waiter
{
private IList<Command> orders = new List<Command>();
//设置订单
public void SetOrder(Command command)
{
if (command.ToString() == "CommandExample.BackChickenWingCommand")
{
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 c in orders)
{
c.ExcuteCommand();
}
}
}
}
// 客户端调用
namespace CommandExample
{
class Program
{
static void Main(string[] args)
{
//开店前的准备
Barbecuer boy = new Barbecuer();
Command bakeMuttonCommand1 = new BakeMuttonCommand(boy);
Command bakeMuttonCommand2 = new BakeMuttonCommand(boy);
Command bakeChickenCommand1 = new BackChickenWingCommand(boy);
Waiter girl = new Waiter();
//开门营业 顾客点菜
girl.SetOrder(bakeMuttonCommand1);
girl.SetOrder(bakeMuttonCommand2);
girl.SetOrder(bakeChickenCommand1);
//订单下好后,一次性通知厨房
girl.Notify();
Console.Read();
}
}
}
五. 优缺点
优点:
- 命令模式能较容易的设计一个命令队列;
- 在需要的情况下,可以较容易的将命令记入日志;
- 允许接收请求的一方决定是否要否决该请求;
- 可以容易的实现对请求的撤销和重构;
- 由于加入新的具体命令类不影响其它的类,因此增加新的具体命令很容易;
- 命令模式把请求一个操作的对象与知道怎么执行一个操作的对象分割开。
六. 应用场景
- 系统需要将请求调用者和请求接收者解耦,使得调用者和接收者不直接交互。
- 系统需要在不同的时间指定请求、将请求排队和执行请求。
- 系统需要支持命令的撤销(Undo)操作和恢复(Redo)操作。
- 系统需要将一组操作组合在一起,即支持宏命令。