命令模式

定义:

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

  在软件系统中,【行为请求者】与【行为实现者】通常是一种紧耦合的关系,但某些场合,比如需要对行为进行记录、撤销或重做等处理时,这种无法抵御变化的紧耦合的设计就不太合适。命令模式就是将请求和实现解耦,以便能方便的实现对行为进行记录、撤销或重做等处理。

结构图:

 

 

 

 

 

 代码(模拟烧烤店):

//Command类(抽象命令类(菜单))

class Command

{

public:

//声明命令执行者(烤串师傅)

  Barbecuer cReceiver;

//定义命令

 void ExcuteCommand() = 0;

}

//Command实现类(具体命令类:烤羊肉串命令)

class MuttonCommand  : Command

{

//调用指定的接收者(烤串师傅)执行命令(烤羊肉串)

public:

   void ExcuteCommand()

  {

    cReceiver.Mutton();

  }

}

//Command实现类(具体命令类:烤鸡命令)

class ChickenCommand  : Command

{

//调用指定的接收者(烤串师傅)执行命令(烤鸡)

public:

   void ExcuteCommand()

  {

    cReceiver.Chicken();

  }

}

//Invoker类(服务员类、请求类,方便理解)

class Waiter

{

Private IList<Command> order;//存放具体命令的容器(客户单)

public:

//下单

  void SetOrder(const Command &cCommand)

  {

    Order.add(cCommand);

    。。。;

  }

//取消订单

  void CancelOrder(const Command &cCommand)

  {

    Order.Remove(cCommand);

    。。。;

  }

//通知执行

  void Notify()

  {

    foreach(command cmd in orders)

    cmd.ExcuteCommand();

  }

}

//Recevie实现类(烧烤师傅)

class Barbecuer

{

public:

  //烤羊肉串

   void Mutton()

  {

    。。。;

  }

  //烤鸡

   void Chicken()

  {

    。。。;

  }

}

 

//客户端

//开店前准备

Barbecuer* cBarbecuer = new Barbecuer();//创建一个烧烤师傅

Waiter* cWaiter = new Waiter ();//创建一个服务员

Command* cMuttonCommand = new MuttonCommand(cBarbecuer)//给命令设置执行者

Command* cChickenCommand = new ChickenCommand(cBarbecuer);//给命令设置执行者

//营业下单

cWaiter.SetOrder(cMuttonCommand);//点一个羊肉串

cWaiter.SetOrder(cChickenCommand);//点一个鸡肉串

cWaiter.CancelOrder(cMuttonCommand);//取消羊肉串

cWaiter.Notify();//下单完成,通知执行

 //如果接收者不止一个类,只需要在Command类中声明不同接收者类,在具体命令中调用执行方法就行了。接收者可以是任何类。

 

使用时机:

  系统需要支持命令的撤销(Undo)操作和恢复(Redo)操作,可以考虑使用命令模式;

 

优点:

1、比较容易的设计一个命令队列;

2、可以比较容易的的将命令记入日志、对请求撤销和重做;

3、很容易新加具体命令类;

4、请求和执行分离,解耦合。

缺点:更多的类,使程序更加复杂。

posted @ 2020-08-23 12:50  吉尔加斯  阅读(174)  评论(0编辑  收藏  举报