Chinaunix首页 | 论坛 | 博客
  • 博客访问: 1814771
  • 博文数量: 438
  • 博客积分: 9799
  • 博客等级: 中将
  • 技术积分: 6092
  • 用 户 组: 普通用户
  • 注册时间: 2012-03-25 17:25
文章分类

全部博文(438)

文章存档

2019年(1)

2013年(8)

2012年(429)

分类: C/C++

2012-03-25 18:56:41

当你投递快递时,是否想过它会怎么被寄到目的地?空运还是海运?这些我们都不关心,只要你的快递有人运送就行。

假设有个接待员来接收你的快递,他可以视为一个Invoker,他的executeCommand方法保证快递正常运送:


  1. class Invoker
  2. {
  3. public:
  4.     void setCommand(Command* pCommand) : mpCommand(pCommand) {}
  5.     void executeCommand() { mpCommand->execute(); }
  6. private:
  7.     Command* mpCommand;
  8. };

setCommand的作用是选择快递公司。快递公司就是一个Command,通过execute方法来运送快递:


  1. class Command
  2. {
  3. public:
  4.     virtual void execute() = 0;
  5.     virtual void setReceiver(Receiver) = 0;
  6. };

你关心的只是哪个快递公司,但它怎么运送,是快递公司的事,你不需要知道。

收件人是一个Receiver:


  1. class Receiver
  2. {
  3. public:
  4.     void action();
  5. };

你,作为上帝,就是Client:


  1. class Client
  2. {
  3. public:
  4.     void post()
  5.     {
  6.         Invoker invoker;
  7.         invoker.setCommand(new SomeCommand(SomeReceiver));
  8.         invoker.executeCommand();
  9.     }
  10. };

你告诉接待员你要哪家快递公司,收件人是谁,然后让他就把快递邮出去。

命令模式的魅力在于Client可以自由选择Command和Receiver,而且Invokder根本就不用了解Command的细节,只需做一个简单的转接。这样接待员的工作才会相当轻松,否则接待员可能需要千里迢迢拔山涉水拿着你的包裹送给收件人,相当杯具……

Invoker可以接收多个Command,这些Command也可以来自不同的Client,所以Invoker也可以这样:


  1. class Invoker
  2. {
  3. public:
  4.     void setCommand(Id);
  5.     void executeCommand(Id);
  6. };


有时我们可能需要一个叫宏命令的东西,它本身是个Command,但是可以把其它一些命令聚合起来一起执行:


  1. class MacroCommand : public Command
  2. {
  3. public:
  4.     Command(Command[] commands) {}
  5.     virtual void execute()
  6.     {
  7.         foreach(Command* pCommand in commands)
  8.             pCommand->execute();
  9.     }
  10. };


Command还有一个很重要的特性,那就是undo:


  1. class Command
  2. {
  3. public:
  4.     virtual void execute() = 0;
  5.     virtual void undo() = 0;
  6. };


Command还可以存储起来,比如服务器突然死机重启后,客户端发过来的Command不会被丢失,仍然会被执行。


  1. class Command
  2. {
  3. public:
  4.     virtual void execute() = 0;
  5.     virtual void undo() = 0;
  6.     virtual void store() = 0;
  7.     virtual void load() = 0;
  8. };

阅读(844) | 评论(0) | 转发(0) |
给主人留下些什么吧!~~