命令模式将一个请求封装成一个对象,从而让你使用不同的请求把客户端参数化,对请求排队或者记录请求日志,可以提供命令的撤销和恢复功能。客户端不需要知道是谁如何实现相应的功能。
这里实现了一种简单的命令模式,不支持恢复功能。
#include <map>
#include <boost/function.hpp>
namespace dp
{
template<class T, typename Method>
class command
{
public:
command(T& receiver, Method m) : m_receiver(receiver), m_do(m) { }
template<typename ID>
void operator()(const ID& id)
{
(m_receiver.*m_do)(id);
}
private:
T& m_receiver;
Method m_do;
};
template<class ID>
class invoker
{
public:
template<class T, class Method>
void insert(const ID& id, T& receiver, Method m)
{
m_commands.insert(std::make_pair(id, command<T, Method>(receiver, m)));
}
void remove(const ID& id)
{
commamd_map::const_iterator it=m_commands.find(id);
if(it!=m_commands.end())
m_commands.erase(it);
}
bool invoke(const ID& id) const
{
commamd_map::const_iterator it=m_commands.find(id);
if(it!=m_commands.end())
{
(it->second)(id);
return true;
}
return false;
}
private:
typedef std::map<ID, boost::function<void(const ID&)> > commamd_map;
commamd_map m_commands;
};
}
下面用一个“最简化”的编辑器应用这个模式:
enum
{
CMD_COPY,
CMD_PASTE,
CMD_CUT,
CMD_DELETE
};
class editor
{
public:
void copy(int)
{
cout<<"copy command"<<endl;
}
void paste(int)
{
cout<<"paste command"<<endl;
}
void cut(int)
{
cout<<"cut command"<<endl;
}
void del(int)
{
cout<<"delete command"<<endl;
}
};
void test()
{
dp::invoker<int> invoker;
editor e;
invoker.insert(CMD_COPY, e, &editor::copy);
invoker.insert(CMD_PASTE, e, &editor::paste);
invoker.insert(CMD_CUT, e, &editor::cut);
invoker.insert(CMD_DELETE, e, &editor::del);
invoker.invoke(CMD_COPY);
invoker.invoke(CMD_DELETE);
}