C++設計模式-Command命令模式


Command命令模式
作用:將一個請求封裝為一個對象,從而使你可用不同的請求對客戶進行參數化;對請求排隊或記錄請求日志,以及支持可撤銷的操作。

由於“行為請求者”與“行為實現者”的緊耦合,使用命令模式,可以對請求排隊或記錄請求日志,以及支持可撤銷的操作。

UML圖:


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 }

 


免責聲明!

本站轉載的文章為個人學習借鑒使用,本站對版權不負任何法律責任。如果侵犯了您的隱私權益,請聯系本站郵箱yoyou2525@163.com刪除。



 
粵ICP備18138465號   © 2018-2025 CODEPRJ.COM