Command(命令)模式的核心思想是将行为的请求者与执行者解耦,从而支持撤销/重做等处理需求。

实现上并不复杂:将请求封装到一个 Command 类中,提供处理对象(Receiver),最后由 Invoker 调用 Execute。

  • 可以通过回调的方式将处理对象封装为参数传入 Command,可用函数指针,也可用匿名函数(lambda)。
  • 处理对象(Receiver)可以有多个处理函数,分别应对不同的命令。
  • 处理对象(Receiver)也可以只有一个统一的处理函数,通过传入 RTTI 类型信息来确定具体操作,实现统一的处理接口。

例1:基础结构

class Receiver
                {
                public:
                	virtual void Action()
                	{
                		cout << __FUNCTION__ << endl;
                	}
                };
                
                
                
                
                class Command
                {
                public:
                	virtual void Execute() = 0;
                
                protected:
                	Receiver*recver;
                
                };
                
                
                
                class ConCreateCommand :public Command
                {
                public:
                	virtual void Execute()override
                	{
                		recver->Action();
                	}
                
                	ConCreateCommand(Receiver*recevier)
                	{
                		this->recver = recevier;
                	}
                
                };
                
                
                class Invoker
                {
                public:
                	void Invoke()
                	{
                		command->Execute();
                	}
                	Invoker(Command *com)
                	{
                		this->command = com;
                	}
                private:
                	Command*command;
                
                };
                
                
                void testCommand()
                {
                	Receiver *recv = new Receiver;
                	ConCreateCommand *com = new ConCreateCommand(recv);
                
                	Invoker *invoke = new Invoker(com);
                
                	invoke->Invoke();
                }

例2:多命令 Receiver

class ReceverTV
                	{
                	public:
                		void ActionVolumeUp()
                		{
                			cout << __FUNCTION__ << endl;
                		}
                		void ActionPowerOn()
                		{
                			cout << __FUNCTION__ << endl;
                		}
                
                	};
                
                
                
                	class Command
                	{
                	public:
                		virtual void Execute() = 0;
                
                	protected:
                		ReceverTV *recv;
                	};
                
                	class CommandOn :public Command
                	{
                	public:
                		virtual void Execute()override
                		{
                			cout << "power on" << endl;
                			recv->ActionPowerOn();
                
                		}
                		CommandOn(ReceverTV *tv)
                		{
                			recv = tv;
                		}
                	};
                
                	class CommandVolumeUp :public Command
                	{
                	public:
                		virtual void Execute()
                		{
                			cout << "volume up" << endl;
                			recv->ActionVolumeUp();
                		}
                		CommandVolumeUp(ReceverTV *tv)
                		{
                			recv = tv;
                		}
                	};
                	class Invoker
                	{
                
                	public:
                		void Invoke()
                		{
                			com->Execute();
                		}
                		Invoker(Command *com)
                		{
                			this->com = com;
                		}
                	private:
                		Command*com;
                	};
                
                
                
                
                	void testCommand2()
                	{
                		ReceverTV*tv = new ReceverTV();
                
                		auto *on = new CommandVolumeUp(tv);
                
                		Invoker *invoke = new Invoker(on);
                		invoke->Invoke();
                
                	}
                
                
                	void testCommand3()
                	{
                		ReceverTV*tv = new ReceverTV();
                		auto *on = new CommandVolumeUp(tv);
                
                		on->Execute();
                	}

例3:回调方式(std::function)

#include <functional>
                
                
                
                	class Receiver
                	{
                	public:
                		virtual void Action()
                		{
                			cout << __FUNCTION__ << endl;
                		}
                	};
                
                
                	class Command
                	{
                	public:
                		virtual void Execute() = 0;
                	};
                
                
                	class CallbackCommand :public Command
                	{
                	public:
                		virtual void Execute()override
                		{
                			if (recever)
                				recever();
                		}
                		CallbackCommand(const std::function<void(void)>& recever)
                		{
                			this->recever = recever;
                		}
                	private:
                		std::function<void(void)> recever = nullptr;
                
                	};
                
                
                	void testCommand4()
                	{
                		Receiver *rev = new Receiver;
                		Command *com = new CallbackCommand([=]()
                		{
                			rev->Action();
                		});
                		com->Execute();
                
                		//RTTI
                	//	cout << typeid(com).hash_code();
                
                		cout << (unsigned int)(com) << endl;;
                
                
                
                
                		{
                			Receiver *rev = new Receiver;
                			Command *com = new CallbackCommand([=]()
                			{
                				rev->Action();
                			});
                			com->Execute();
                
                			//RTTI
                			//cout << typeid(com).hash_code();
                			cout << (unsigned int)(com) << endl;
                
                
                		}
                	//	cout <<  (unsigned int)(com);
                
                
                
                	}