【C++設計模式】命令模式
阿新 • • 發佈:2018-12-12
#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(); }