版权声明:本文为博主原创文章,未经博主允许不得转载。 https://blog.csdn.net/zxh2075/article/details/82878909
#ifndef __COMMAND_H__
#define __COMMAND_H__
#include <iostream>
#include <list>
//命令模式(Command):将一个请求封装成一个对象(Command对象),并赋予该对象一个执行接口。
//从而使你可用不同的请求对客户进行参数化;对请求排队或记录请求日志,以及支持可撤销的操作。
//Command对象在执行命令时,并不一定自己切身做这件事,而是将请求转发给另一个真正做这件事情的对象(Receiver对象),由Receiver对象最终完成请求操作。
//Command类,用来声明执行操作的接口
class iCommand
{
public:
virtual void execute() = 0;
};
//Receiver类,真正执行请求相关操作的接口,任何类都可能作为一个接收者。
class iReceiver
{
public:
virtual void execute() = 0;
};
//播放音乐命令
class PlayCommand : public iCommand
{
public:
PlayCommand(iReceiver* recv);
virtual void execute();
private:
iReceiver *m_recv;
};
//烹饪命令
class CookCommand : public iCommand
{
public:
CookCommand(iReceiver* recv);
virtual void execute();
private:
iReceiver *m_recv;
};
//播放器
class MediaPlayer : public iReceiver
{
public:
virtual void execute();
};
//厨师
class Chef : public iReceiver
{
public:
virtual void execute();
};
//如果客户端需要多种命令能够按照某个队列依次执行,我们需要把命令的执行者从客户端中分离出来。
//引入一个对象叫调度者,Invoker类,来控制命令的队列化和可撤销操作等,对命令进行管理。
class Invoker
{
public:
void AddCommand(iCommand* cmd);
int ExecuteCommand();
void CancelCommand(iCommand *com);
void RollbackCommand(iCommand *com);
private:
std::list<iCommand*> m_cmdlist;
std::list<iCommand*> m_historycmdlist;
};
void TestCommand();
#endif
#include "Command.h"
PlayCommand::PlayCommand(iReceiver* recv) : m_recv(recv)
{
}
void PlayCommand::execute()
{
m_recv->execute();
}
CookCommand::CookCommand(iReceiver* recv) : m_recv(recv)
{
}
void CookCommand::execute()
{
m_recv->execute();
}
void MediaPlayer::execute()
{
printf("start play music .\n");
}
void Chef::execute()
{
printf("start cook .\n");
}
void Invoker::AddCommand(iCommand* cmd)
{
m_cmdlist.push_back(cmd);
}
int Invoker::ExecuteCommand()
{
if (!m_cmdlist.empty())
{
iCommand * cmd = NULL;
cmd = m_cmdlist.front();
cmd->execute();
m_cmdlist.pop_front();
m_historycmdlist.push_back(cmd);
}
return -1;
}
void Invoker::CancelCommand(iCommand *com)
{
//遍历命令队列,找到命令并删除
}
void Invoker::RollbackCommand(iCommand *com)
{
//找到历史命令,并执行状态还原
}
void TestCommand()
{
iReceiver *chef = new Chef();
iCommand *cookcmd = new CookCommand(chef);
iReceiver *player = new MediaPlayer();
iCommand *playcmd = new PlayCommand(player);
Invoker *inv = new Invoker();
inv->AddCommand(playcmd);
inv->AddCommand(cookcmd);
inv->ExecuteCommand();
inv->ExecuteCommand();
}