设计模式【19】——命令模式(Command模式)


前言

日常生活中,我们去饭馆吃饭一般都是找服务员点菜,而不是直接给厨师下菜单?其实,这种点菜的方式就是命令模式:我们点的菜单就是一个个请求,点菜员记录的菜单就是将请求生成的对象,点菜员不需要关心怎么做菜、谁来做,他只要把菜单传到后厨即可,由后厨统一调度。
简而言之,命令模式就是把请求以命令的形式包裹在对象中,并传给调用对象。调用对象寻找可以处理该命令的合适的对象,并把该命令传给相应的对象,该对象执行命令。


一、命令模式(Command模式)

Command 模式中,将请求的接收者(Reciever)放到 Command 的具体子类ConcreteCommand 中,当请求到来时(Invoker 发出 Invoke 消息激活 Command 对象),ConcreteCommand 将处理请求交给 Receiver 对象进行处理。UML图如下:
Command模式示意图


二、具体源码

1.Reciever.h

代码如下(示例):

#ifndef _RECIEVER_H_ 
#define _RECIEVER_H_ 

#include <iostream>

class Reciever
{
public:

  Reciever();
  ~Reciever();
  void Action();

protected:
private:
};
#endif //_RECIEVER_H_

2.Reciever.cpp

代码如下(示例):

#include "Reciever.h" 

Reciever::Reciever()
{
}

Reciever::~Reciever()
{
}

void Reciever::Action()
{
  std::cout << "Reciever action......." << std::endl;
}

3.Command.h

代码如下(示例):

#pragma once
#ifndef _COMMAND_H_ 
#define _COMMAND_H_ 

#include "Reciever.h"

class Command
{
public:
  virtual ~Command();
  virtual void Excute() = 0;

protected:
  Command();
private:
};

class ConcreteCommand :public Command
{
public:
  ConcreteCommand(Reciever* rev);
  ~ConcreteCommand();
  void Excute();

protected:
private:
  Reciever* _rev;
};

#endif //_COMMAND_H_

4.Command.cpp

代码如下(示例):

#include "Command.h" 

Command::Command()
{
}

Command::~Command()
{
}

void Command::Excute()
{
}

ConcreteCommand::ConcreteCommand(Reciever* rev)
{
  this->_rev = rev;
}

ConcreteCommand::~ConcreteCommand()
{
  delete this->_rev;
}

void ConcreteCommand::Excute()
{
  _rev->Action();
  std::cout << "ConcreteCommand..." << std::endl;
}

5.Invoker.h

代码如下(示例):

#pragma once
#ifndef _INVOKER_H_ 
#define _INVOKER_H_

#include "Command.h"

class Invoker
{
public:
  Invoker(Command* cmd);
  ~Invoker();
  void Invoke();

protected:
private:
  Command* _cmd;
};

#endif //_INVOKER_H_

6.Invoker.cpp

代码如下(示例):

#include "Invoker.h" 

Invoker::Invoker(Command* cmd)
{
  _cmd = cmd;
}

Invoker::~Invoker()
{
  delete _cmd;
}

void Invoker::Invoke()
{
  _cmd->Excute();
}

7.main.cpp

代码如下(示例):

#include "Command.h" 
#include "Invoker.h" 
#include "Reciever.h" 


int main(int argc, char* argv[])
{
  Reciever* rev = new Reciever();
  Command* cmd = new ConcreteCommand(rev);
  Invoker* inv = new Invoker(cmd);

  inv->Invoke();
  return 0;
}

三、运行结果

Command模式运行结果如下:
Command模式运行结果


总结

Command 模式的思想非常简单,而且也十分常见。实际上,Command 模式关键就是提供一个抽象的 Command 类,并将执行操作封装到 Command类接口中,Command 类中一般就是只是一些接口的集合,并不包含任何的数据属性(当然在示例代码中,我们的 Command 类有一个处理操作的 Receiver 类的引用,但是其作用也仅仅就是为了实现这个 Command 的 Excute 接口)。Command 模式的优点如下:
1)将调用操作的对象和知道如何实现该操作的对象解耦。如上,Invoker 对象根本就不知道具体的是那个对象在处理 Excute操作;
2)增加新的处理操作对象很容易,只需通过创建新的继承自Command 的子类来实现即可。


本文参考《设计模式精解-GoF 23 种设计模式解析附 C++实现源码》,对内容进行整理,方便大家学习。如想学习详细内容,请参考此书。

  • 0
    点赞
  • 1
    收藏
    觉得还不错? 一键收藏
  • 打赏
    打赏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

希望早日退休的程序猿

你的鼓励将是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值