1. 程式人生 > 其它 >C++設計模式 - 命令模式(Command)

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

行為變化模式

  • 在元件的構建過程中,元件行為的變化經常導致元件本身劇烈的變化。“行為變化” 模式將元件的行為和元件本身進行解耦,從而支援元件行為的變化,實現兩者之間的鬆耦合。

典型模式

  • Command
  • Visitor

Command

動機( Motivation )

  • 在軟體構建過程中,“行為請求者” 與"行為實現者”通常呈現一種“緊耦合”。但在某些場合一比如需 要對行為進行“記錄、撤銷/重(undo/redo)、事務”等處理,這種無法抵禦變化的緊耦合是不合適的。
  • 在這種情況下,如何將“行為請求者”與“行為實現者”解耦?將一組行為抽象為物件,可以實現二者之間的鬆耦合。

模式定義

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

結構

要點總結

  • Command模式的根本目的在於將“行為請求者”與“行為實現者”解耦,在面嚮物件語言中,常見的實現手段是“將行為抽象為物件”
  • 實現Command介面的具體命令物件ConcreteCommand有時候根據需要可能會儲存一些額外的狀態資訊。通過使用Composite模式 ,可以將多個”命令”封裝為一個“複合命令”MacroCommand.
  • Command模式與C++中的函式物件有些類似。但兩者定義行為介面的規範有所區別: Command以面向物件中的' 介面-實現”來定義行為介面規範,更嚴格,但有效能損失; C++函式物件以函式簽名來定義行為介面規範,更靈活,效能更高。

cpp

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

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

class ConcreteCommand1 :public Command
{
public:
	ConcreteCommand1(const std::string& str) :arg(str) {}
	void execute() override
	{
		std::cout << "#1 process..." << arg << std::endl;
	}
private:
	std::string arg;
};

class ConcreteCommand2 :public Command
{
public:
	ConcreteCommand2(const std::string& str) :arg(str) {}
	void execute() override
	{
		std::cout << "#2 process..." << arg << std::endl;
	}
private:
	std::string arg;
};

class MacroCommand :public Command
{
public:
	void addCommand(Command* command) { commands.push_back(command); }
	void execute() override
	{
		for (auto& c : commands)
		{
			c->execute();
		}
	}
private:
	std::vector<Command*>commands;
};


int main()
{
	ConcreteCommand1 command1("Arg ###");
	ConcreteCommand2 command2("Arg $$$");

	MacroCommand macro;
	macro.addCommand(&command1);
	macro.addCommand(&command2);

	macro.execute();
	return 0;
}