【命令模式】
命令模式(Command),将一个请求封装为一个对象,从而使你可用不同的请求对客户进行参数化,对请求进行排队或者使记录请求日志,以及支持可撤销的操作
【介绍】
-
主要解决:在软件系统中,行为请求者与行为实现者通常是一种紧耦合的关系,但是某些场合,需要对行为进行纪录、撤销或者重做、事务等处理时候
-
何时使用:将一组行为先抽象为对象,可以事先二者之间的松耦合
-
如何解决:通过调用者调用接收者执行命令,顺序:调用者——接收者——命令
-
关键代码:三个角色——received真正的命令执行对象;command;invoker使用命令对象的入口
-
优点:降低了系统的耦合度、新的命令可以很容易的添加到系统中去
-
缺点:使用命令模式可能会导致某些系统有过的具体命令类
-
注意事项:系统需要支持命令的撤销操作和恢复操作
【实现】
步骤一:抽象命令
public abstract class Command
{
protected Barbecuer receiver;
public Command (Barbecuer receiver)//确定厨师是谁
{
this.receiver = receiver;
}
//执行命令
abstract public void ExcuteCommand();
}
步骤二:具体命令类
class BraisedFishCommand : Command//红烧鱼命令
{
public BraisedFishCommand(Barbecuer receiver):base (receiver)
{
}
public override void ExcuteCommand()
{
receiver.BraisedFish();
}
}
class YuXiangFishCommand : Command//鱼香肉丝命令
{
public YuXiangFishCommand(Barbecuer receiver) : base(receiver)
{
}
public override void ExcuteCommand()
{
receiver.YuXiangFish();
}
}
步骤三:服务员类
public class Waiter
{
private IList<Command> orders= new List<Command >();
//设置订单
public void SetOrder(Command command)
{
if (command .ToString () == "命令模式.BraisedFishCommand")
{
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();
}
}
}
步骤四:厨师类
public class Barbecuer
{
//做红烧鱼
public void BraisedFish()
{
Console.WriteLine("做红烧鱼");
}
//做鱼香肉丝
public void YuXiangFish()
{
Console.WriteLine("做鱼香肉丝");
}
}
步骤五:客户端代码
static void Main(string[] args)
{
//开店前的准备
Barbecuer boy = new Barbecuer();
Command BraisedFishCommand1 = new BraisedFishCommand(boy);
Command BraisedFishCommand2 = new BraisedFishCommand(boy);
Command YuXiangFishCommand1 = new YuXiangFishCommand(boy);
Waiter girl = new Waiter();
//门店事先找好厨师和服务员
//开门营业
girl.SetOrder(BraisedFishCommand1);
girl.SetOrder(YuXiangFishCommand1);
girl.SetOrder(BraisedFishCommand2);
girl.Notify();
Console.Read();
}
【总结】
一、命令模式的优点
-
能比较容易的设计一个命令队列
-
在需要的情况下,可以比较容易的将命令记入日志
-
允许接受请求的一方决定是否要否决请求
-
可以容易的实现对请求的撤销和重做
-
添加新的具体命令类不影响其他的类,增加新的具体命令类很容易
-
命令模式把请求一个操作的对象与指导怎么执行一个操作的对象分割开