C++设计模式-Command命令模式

Command命令模式

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

由于“行为请求者”与“行为实现者”的紧耦合,使用命令模式,可以对请求排队或记录请求日志,以及支持可撤销的操作。

UML图:

C++设计模式-Command命令模式

Command类,用来声明执行操作的接口

ConcreteCommand,将一个接收者对象绑定于一个操作,调用接收者相应的操作,以实现Execute

Invoker类,要求该命令执行这个请求

Receiver类,知道如何实施与执行一个与请求相关的操作,任何类都可能作为一个接收者。



Command模式通过将请求封装到一个对象Command中,并将请求的接收者存放到具体的ConcreteCommand类中,从而实现调用操作的对象和操作的具体实现者之间的解耦。



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



命令模式的优点:

1,它能较容易地设计一个命令队列;

2,在需要的情况下,可以较容易地将命令记入日志;

3,允许接收请求的一方决定是否要否决请求。

4,可以容易地实现对请求的撤销和重做;

5,由于加进新的具体命令类不影响其他的类,因此增加新的具体命令类很容易。



命令模式把请求一个操作的对象与知道怎么执行一个操作的对象分割开。



Command模式关键就是讲一个请求封装到一个类中(Command),再提供处理对象(Receiver),最后Command命令由Invoker激活。另外,我们可以将请求接收者的处理抽象出来作为参数传给Command对象,实际也就是回调的机制来实现这一点。也就是讲处理操作方法地址通过参数传递给Command对象,Command对象在适当的时候再调用该函数。

Command模式将调用操作的对象和知道如何实现该操作的对象解耦,在上面Command的结构图中,Invoker对象根本就不知道具体的是哪个对象在处理Execute操作(当然要知道是Command类别的对象)。

在Command要增加新的处理操作对象很容易,我们可以通过创建新的继承自Command的子类来实现这一点。

Command模式可以和Memento模式结合起来,支持取消的操作。

代码如下:

Command.h

1 #ifndef _COMMAND_H_
 2 #define _COMMAND_H_
 3 
 4 class Command
 5 {
 6 public:
 7     virtual ~Command();
 8     virtual void Execute()=0;
 9 protected:
10     Command();
11 private:
12 };
13 
14 class Receiver;
15 
16 class ConcreteCommand : public Command
17 {
18 public:
19     ConcreteCommand(Receiver* pReceiver);
20     ~ConcreteCommand();
21     virtual void Execute();
22 protected:
23 private:
24     Receiver* _recv;
25 };
26 
27 class Invoker
28 {
29 public:
30     Invoker(Command* pCommand);
31     ~Invoker();
32     void Invoke();
33 protected:
34 private:
35     Command* _cmd;
36 };
37 
38 class Receiver
39 {
40 public:
41     Receiver();
42     ~Receiver();
43     void Action();
44 protected:
45 private:
46 };
47 #endif

Command.cpp

1 #include "Command.h"
 2 #include <iostream>
 3 
 4 using namespace std;
 5 
 6 Command::Command()
 7 {}
 8 
 9 Command::~Command()
10 {}
11 
12 ConcreteCommand::ConcreteCommand(Receiver* pReceiver)
13 {
14     this->_recv = pReceiver;
15 }
16 
17 ConcreteCommand::~ConcreteCommand()
18 {}
19 
20 void ConcreteCommand::Execute()
21 {
22     this->_recv->Action();
23 }
24 
25 Receiver::Receiver()
26 {}
27 
28 Receiver::~Receiver()
29 {}
30 
31 void Receiver::Action()
32 {
33     cout << "Receiver::Action" << endl;
34 }
35 
36 Invoker::Invoker(Command* pCommand)
37 {
38     this->_cmd = pCommand;
39 }
40 
41 Invoker::~Invoker()
42 {}
43 
44 void Invoker::Invoke()
45 {
46     this->_cmd->Execute();
47 }

main.cpp

1 #include "Command.h"
 2 
 3 int main()
 4 {
 5     //创建具体命令对象pCmd并设定它的接收者pRev
 6     Receiver* pRev = new Receiver();
 7     Command* pCmd = new ConcreteCommand(pRev);
 8     //请求绑定命令
 9     Invoker* pInv = new Invoker(pCmd);
10     pInv->Invoke();
11 
12     return 0;
13 }

原文链接: https://www.cnblogs.com/jiese/p/3190414.html

欢迎关注

微信关注下方公众号,第一时间获取干货硬货;公众号内回复【pdf】免费获取数百本计算机经典书籍

原创文章受到原创版权保护。转载请注明出处:https://www.ccppcoding.com/archives/95876

非原创文章文中已经注明原地址,如有侵权,联系删除

关注公众号【高性能架构探索】,第一时间获取最新文章

转载文章受原作者版权保护。转载请注明原作者出处!

(0)
上一篇 2023年2月10日 上午3:18
下一篇 2023年2月10日 上午3:19

相关推荐