C++設計模式——命令模式(command pattern)

三公子Tjq發表於2020-10-28

一、原理講解

別名動作(action),事務(transaction)。

1.1意圖

將一個請求封裝為一個物件,從而使我們可用不同的請求對客戶進行引數化,對請求排隊或記錄請求日誌,以及支援可撤銷的操作。

1.2應用場景

  • 抽象出待執行的動作以引數化某物件;
  • 在不同的時刻指定、排列和執行請求;(比如跨程式傳遞命令物件)
  • 支援取消操作;
  • 支援修改日誌,當系統奔潰時這些修改可被重做一次;
  • 用構建在原語操作上的高層操作構造一個系統;

1.3結構圖(UML圖)

命令模式UML結構圖

1.4程式碼實現步驟

a1 定義介面命令類Command,定義一個執行介面函式execute();
a2 定義一個具體命令類ConcreteCommand,重寫介面函式execute(),並且定義一個接收者指標Receiver reveiver,該指標reveiver對呼叫者類Invoker隱藏;
a3 定義一個接收者類Receiver,定義一個動作函式action(),裡面實現接收到命令的具體業務邏輯;
a4 定義一個呼叫者類Invoker,定義一個介面函式executeCommand(),並且定義一個命令指標Command *command,通過該指標執行和處理命令;

二、實現程式碼

CommandPattern.cpp

#include <iostream>
#include <string>
#include <vector>

using namespace std;

#define DELETE(pointer) delete (pointer); (pointer)=nullptr

class Receiver
{
public:
	void action() { cout << "Receiver::action()" << endl; }
};

class Command
{
public:
	virtual ~Command() {}
	virtual void execute() = 0; // 執行函式
};

class ConcreteCommand : public Command
{
	Receiver *receiver; // 接收者,只對Command開放,對Invoker隱藏
public:
	ConcreteCommand(Receiver *receiver) : receiver(receiver){}
	void execute() override { receiver->action(); }
};

class Invoker
{
	Command *command;
public:
	Invoker() :command(nullptr) {}
	bool setCommand(Command *command) {
		if (command == nullptr)
			return false;
		this->command = command;
		return true;
	}
	void executeCommand() {
		if (command == nullptr)
			return ;
		command->execute();
	}
};

void doCommandPattern()
{
	Receiver *receiver = new Receiver();
	Command *command = new ConcreteCommand(receiver);
	Invoker *invoker = new Invoker();
	if (!invoker->setCommand(command))
	{
		cout << "set command err, please repeate operation!" << endl;
		return;
	}
	invoker->executeCommand();

	DELETE(receiver);
	DELETE(command);
	DELETE(invoker);
}

mian.cpp

#include <iostream>

extern void doCommandPattern();

int main()
{
	doCommandPattern();
	
	system("pause");
	return 1;
}

輸出結果圖

三、總結

命令模式主要是將請求封裝成物件,從而用不同引數對客戶端進行引數化。實現的主要思路是命令類做執行操作,接收者類做具體動作action,呼叫者類呼叫命令類指標實現具體命令功能流程。

3.1相關模式

  • Composite可用來實現巨集命令;
  • Memento可用來保持某個狀態,命令用這一狀態來取消它的效果;

四、參考內容

命令模式C++實現
Command Pattern – 命令模式原理及實現(C++)
設計模式–命令模式C++實現
C++設計模式—命令模式
陳建忠設計模式(參考:嗶哩嗶哩C++設計模式!!!)
Erich Gamma,Richard Helm.《設計模式 可複用物件導向軟體的基礎》[M].機械工業出版社,2019:

相關文章