您的位置:首页 > 其它

设计模式之命令模式

2013-09-17 21:41 316 查看
名词解释:

命令模式:将一个请求封装为一个对象,从而使你可用不同的请求对客户进行参数化;对请求排队或记录请求日志,以及支持可撤销的操作.

必要元素:

1.用于执行操作的接口(抽象类);
2.一个或者多个实现(继承)自操作接口的类;
3.用于执行命令的类;
4.接收者,用于实施与请求相关的操作。

上例子:

命令接口:

abstract class Command
{
protected Receiver receiver;
public Command(Receiver receiver)
{
this.receiver = receiver;
}
public abstract void Execute();
}


接口实现类:

class ConcreteCommand : Command
{
public ConcreteCommand(Receiver receiver)
: base(receiver)
{ }

public override void Execute()
{
receiver.Action();
}
}


执行请求类(接收者,也就是命令执行的操作就是该类的行为):

class Receiver
{
public void Action()
{
Console.WriteLine("执行请求!");
}
}


执行命令类:

class Invoker
{
private Command command;
public void SetCommand(Command command)
{
this.command = command;
}
public void ExecuteCommand()
{
command.Execute();
}
}


调用:

       Receiver r = new Receiver();
Command c = new ConcreteCommand(r);
Invoker i = new Invoker();

i.SetCommand(c);
i.ExecuteCommand();

Console.Read();


例子二(由于上述例子只是代码的构成部分,通过一个厨师做羊肉串和炸鸡翅,以及服务员向顾客询问点餐,这样一个场景):

抽象命令:

abstract class Command
{
protected Barbecuer receiver;
public Command(Barbecuer receiver)
{
this.receiver=receiver;
}

public abstract void ExecuteCommand();
}


具体命令:

  /// <summary>
/// 烤鸡翅命令
/// </summary>
class BakeChickenWingCommand:Command
{
public BakeChickenWingCommand(Barbecuer receiver)
: base(receiver) { }
public override void ExecuteCommand()
{
receiver.BakeChickenWing();
}
}

  /// <summary>
/// 羊肉串命令
/// </summary>
class BakeMuttonCommand:Command
{
public BakeMuttonCommand(Barbecuer receiver)
: base(receiver)
{ }
public override void ExecuteCommand()
{
receiver.BakeMutton();
}
}


厨师类(也就是执行请求类):

class Barbecuer
{
public void BakeMutton()
{
Console.WriteLine("烤羊肉串!");
}

public void BakeChickenWing()
{
Console.WriteLine("烤鸡翅!");
}
}


服务员类(执行命令):

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

public void SetCommand(Command command)
{
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 (var command in orders)
{
command.ExecuteCommand();
}
}
}


调用:

Barbecuer boy = new Barbecuer();
Command bakeMuttonCommand1 = new BakeMuttonCommand(boy);
Command bakeMuttonCommand2 = new BakeMuttonCommand(boy);
Command bakeChickenWingCommand1 = new BakeChickenWingCommand(boy);

Waiter girl = new Waiter();
girl.SetCommand(bakeMuttonCommand1);
girl.SetCommand(bakeMuttonCommand2);
girl.SetCommand(bakeChickenWingCommand1);

girl.Notify();

Console.Read();


整个过程和我们的必要元素是一一对应的,在Command中依赖Receiver(也就是真正执行命令的),在Invoke(Waiter也就是服务员,可以进行命令的增加和移除,实现命令队列)中也是放入Command进行命令的执行。最终的调用过程也是一层层的进行设置,不管是Receiver的设置还是Command的增加移除。

总结:

命令模式的优点:较容易实现一个命令队列;容易将命令记入日志;容易实现对请求的撤销和重做;增加新命令也较容易。
内容来自用户分享和网络整理,不保证内容的准确性,如有侵权内容,可联系管理员处理 点击这里给我发消息
标签: