一. 舉例說明
我們知道,在多線程程序中,多個用戶都給系統發 Read 和 Write 命令。這裡有幾點需要說明:
1. 首先明確一點,所有的這些 Read 和 Write 命令都是調用一個庫函數。
2. 用戶並不需要知道別的用戶的存在,也不管別人發不發命令,只管自己發命令,最後給結果即可。
3. 這些命令先是到了一個消息隊列裡面,然後由消息隊列調用庫函數。
結構圖如下:
代碼如下:
[cpp] class Command;
//實施與執行類
class Reciever
{
public:
void Action()
{
cout<<"Do action !!"<<endl;
}
};
//抽象命令類
class Command
{
public:
virtual ~Command() {}
virtual void Excute() = 0;
protected:
Command() {}
};
//Read 命令
class Read_Command:public Command
{
public:
Read_Command(Reciever* rev)
{
this->_rev = rev;
}
~Read_Command()
{
delete this->_rev;
}
void Excute()
{
cout<<"Read Command..."<<endl;
_rev->Action();
}
private:
Reciever* _rev;
};
//Write 命令
class Write_Command:public Command
{
public:
Write_Command(Reciever* rev)
{
this->_rev = rev;
}
~Write_Command()
{
delete this->_rev;
}
void Excute()
{
cout<<"Write_Command..."<<endl;
_rev->Action();
}
private:
Reciever* _rev;
};
//要求命令執行的類
class Invoker
{
public:
Invoker(Command* cmd)
{
_cmd = cmd;
}
Invoker()
{
}
~Invoker()
{
delete _cmd;
}
//通知執行類執行
void Notify()
{
list<Command*>::iterator it = cmdList.begin();
for (it; it != cmdList.end(); ++it)
{
_cmd = *it;
_cmd->Excute();
}
}
//添加命令
void AddCmd(Command* pcmd)
{
cmdList.push_back(pcmd);
}
//刪除命令
void DelCmd(Command* pcmd)
{
cmdList.remove(pcmd);
}
private:
Command* _cmd;
list<Command*> cmdList;
};
//測試代碼 www.2cto.com
int main(int argc,char* argv[])
{
Reciever* rev = new Reciever(); //定義一個執行類
Command* cmd1 = new Read_Command(rev);//Read 命令
Command* cmd2 = new Write_Command(rev);//Write 命令
Invoker inv; //管理所有命令
inv.AddCmd(cmd1);
inv.AddCmd(cmd2);
inv.Notify(); //通知執行類,執行
inv.DelCmd(cmd1);
inv.Notify();
return 0;
}
class Command;
//實施與執行類
class Reciever
{
public:
void Action()
{
cout<<"Do action !!"<<endl;
}
};
//抽象命令類
class Command
{
public:
virtual ~Command() {}
virtual void Excute() = 0;
protected:
Command() {}
};
//Read 命令
class Read_Command:public Command
{
public:
Read_Command(Reciever* rev)
{
this->_rev = rev;
}
~Read_Command()
{
delete this->_rev;
}
void Excute()
{
cout<<"Read Command..."<<endl;
_rev->Action();
}
private:
Reciever* _rev;
};
//Write 命令
class Write_Command:public Command
{
public:
Write_Command(Reciever* rev)
{
this->_rev = rev;
}
~Write_Command()
{
delete this->_rev;
}
void Excute()
{
cout<<"Write_Command..."<<endl;
_rev->Action();
}
private:
Reciever* _rev;
};
//要求命令執行的類
class Invoker
{
public:
Invoker(Command* cmd)
{
_cmd = cmd;
}
Invoker()
{
}
~Invoker()
{
delete _cmd;
}
//通知執行類執行
void Notify()
{
list<Command*>::iterator it = cmdList.begin();
for (it; it != cmdList.end(); ++it)
{
_cmd = *it;
_cmd->Excute();
}
}
//添加命令
void AddCmd(Command* pcmd)
{
cmdList.push_back(pcmd);
}
//刪除命令
void DelCmd(Command* pcmd)
{
cmdList.remove(pcmd);
}
private:
Command* _cmd;
list<Command*> cmdList;
};
//測試代碼
int main(int argc,char* argv[])
{
Reciever* rev = new Reciever(); //定義一個執行類
Command* cmd1 = new Read_Command(rev);//Read 命令
Command* cmd2 = new Write_Command(rev);//Write 命令
Invoker inv; //管理所有命令
inv.AddCmd(cmd1);
inv.AddCmd(cmd2);
inv.Notify(); //通知執行類,執行
inv.DelCmd(cmd1);
inv.Notify();
return 0;
}
二. 命令模式
定義:將一個請求封裝為一個對象,從而使你可用不同的請求對客戶時行參數化;對請求排隊或記錄請求日志,以及支持可撤銷的操作。
優點:
1. 它能比較容易地設計一個命令隊列。
2. 在需要的情況下,可以較容易地將命令記入日志。
3. 允許接收請求的一方決定是否要否決請求。
4. 可以容易地實現對請求的撤銷和重做。
5. 增加新的具體命令類很容易
6. 把請求一個操作的對象(Command)與知道怎麼執行一個操作的對象(Receiver)分割開來。
作者 lwbeyond