【C++设计模式】命令模式

版权声明:本文为博主原创文章,未经博主允许不得转载。 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();
}

猜你喜欢

转载自blog.csdn.net/zxh2075/article/details/82878909