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);
}