命令模式(c++實現)
阿新 • • 發佈:2020-07-15
命令模式
目錄
模式定義
命令模式(Facade),將一個請求封裝為一個物件,從而使你可用不同的請求對客戶進行引數化;對請求排隊或記錄請求日誌,以及支援可撤銷的操作。
模式動機
- 敏捷開發的原則告訴我們,不要為程式碼新增基於猜測的、實際不需要的功能。如果不清楚一個系統是否需要命令模式,一般就不要著急去實現它,事實上,在需要的時候通過重構實現這個模式並不困難,只有在真正需要如撤銷/恢復操作等功能時,把原來的程式碼重構為命令模式才有意義。
UML類圖
原始碼實現
- command.h
#include "chef.h" class Command { public: Command(Chef* chef); virtual ~Command(); virtual void ExcuteCmd(); protected: Chef* m_Chef; };
- chef.h
class Chef
{
public:
Chef();
void KungPaoChicken();
void FishFlavoredShreddedPork();
void BigPlateChicken();
};
- chef.cpp
#include "chef.h" #include <iostream> Chef::Chef() { } void Chef::KungPaoChicken() { std::cout << "宮保雞丁" << std::endl; } void Chef::FishFlavoredShreddedPork() { std::cout << "魚香肉絲" << std::endl; } void Chef::BigPlateChicken() { std::cout << "大盤雞" << std::endl; }
- kungpaochickencmd.h
#include "command.h"
#include "chef.h"
class KungPaoChickenCmd : public Command
{
public:
KungPaoChickenCmd(Chef* chef);
void ExcuteCmd() override;
};
- kungpaochickencmd.cpp
#include "kungpaochickencmd.h" KungPaoChickenCmd::KungPaoChickenCmd(Chef* chef) :Command(chef) { } void KungPaoChickenCmd::ExcuteCmd() { m_Chef->KungPaoChicken(); }
- waiter.h
#include <list>
#include <command.h>
class Waiter
{
public:
Waiter();
void AddCmd(Command* cmd);
void DelCmd(Command* cmd);
void Nodify();
private:
std::list<Command*> m_CmdList;
};
- waiter.cpp
#include "waiter.h"
Waiter::Waiter()
{
}
void Waiter::AddCmd(Command *cmd)
{
m_CmdList.push_back(cmd);
}
void Waiter::DelCmd(Command *cmd)
{
m_CmdList.remove(cmd);
}
void Waiter::Nodify()
{
for(auto cmd : m_CmdList)
{
if(cmd)
cmd->ExcuteCmd();
}
}
- main.cpp
#include <iostream>
#include "fishflavoredshreddedporkcmd.h"
#include "kungpaochickencmd.h"
#include "bigplatechickencmd.h"
#include "waiter.h"
#include <memory>
int main()
{
Chef* chef = new Chef();
Waiter waiter;
std::shared_ptr<FishFlavoredShreddedPorkCmd> ffspc = std::make_shared<FishFlavoredShreddedPorkCmd>(chef);
std::shared_ptr<KungPaoChickenCmd> kpcc = std::make_shared<KungPaoChickenCmd>(chef);
std::shared_ptr<BigPlateChickenCmd> bpcc = std::make_shared<BigPlateChickenCmd>(chef);
waiter.AddCmd(ffspc.get());
waiter.AddCmd(kpcc.get());
waiter.AddCmd(bpcc.get());
// waiter.DelCmd(kpcc.get);
waiter.Nodify();
return 0;
}
- 執行結果
魚香肉絲
宮保雞丁
大盤雞
優點
命令模式的優點
- 它能較容易的設計一個命令佇列;
- 在需要的情況下,可以較容易的將命令計入日誌;
- 允許接收請求的一方決定是否要否決請求;
- 可以容易的實現對請求的撤銷和重做;
- 由於加進新的具體命令類不影響其他的類,因此增加新的具體命令類很容易;
- 把請求一個操作的物件與知道怎麼執行一個操作的物件分隔開;
缺點
模式的缺點