遊戲程式設計模式學習:第一章命令模式
命令模式:將一個請求封裝成一個物件,從而允許你使用不同的請求,佇列或者日誌將客戶端引數化,同
時支援請求操作的撤銷與恢復;
主要目的
該設計模式主要是為了隔離請求和實際執行者之間接觸,實現兩者的解耦。所有的請求統一有一個類負責
該類負責管理這些請求。這樣命令物件和接收者之間的耦合度就會降低。命令物件不用直接施加命令到接收者上。
而會通過施加命令到命令介面,通過命令介面例項化出來一個相應的命令,從而施加到接收者上。
具體例子:
1.我們去餐廳吃飯,我們是通過服務員來點菜,具體是誰來做這些菜和他們什麼時候完成的這些菜,其實我們都不知道。抽象之,我們是“選單請求者”,廚師是“選單實現者”,2者之間是鬆耦合的,我們對這些菜的其他一些請求比如“撤銷,重做”等,我們也不知道是誰在做。其實這就是本文要說的Command模式。將一個請求封裝為一個物件,從而使你可用不同的請求對客戶進行引數化;對請求排隊或記錄請求日誌,以及支援可撤消的操作。[GOF 《設計模式》]
#include <iostream>
#include <string>
#include <vector>
using namespace std;
#define SAFE_DELETE(p) if (p) { delete p; p = NULL; }//安全刪除
//燒烤師傅類,最後的執行者
class Barbecuer
{
public:
void BakeMutton()
{
cout << "Bake Mutton" << endl;
}
void BakeChickenWing()
{
cout << "Bake ChickenWing" << endl;
}
};
//抽象命令類:執行具體操作的介面
class Command
{
public:
Command() {};
Command(Barbecuer* receiver):p_receiver(receiver) {}
virtual void ExecuteCommand() = 0;
protected:
Barbecuer* p_receiver;
};
//具體命令,烤羊肉串命令
class BakeMuttonCommand:public Command
{
public :
BakeMuttonCommand(Barbecuer* receiver)
{
p_receiver = receiver;
}
void ExecuteCommand()
{
p_receiver->BakeMutton();
}
};
//具體命令,烤雞翅命令
class BakeChickenWingCommand :public Command
{
public:
BakeChickenWingCommand(Barbecuer* receiver)
{
p_receiver=receiver;
}
void ExecuteCommand()
{
p_receiver->BakeChickenWing();
}
};
//服務員類,相當於命令者
class Waiter
{
public:
void SetOrder(Command* command);//相當於一個命令佇列
void Notify();
private:
vector<Command*>p_Commandlist;
};
//按照順序給佇列內新增相應的命令
void Waiter::SetOrder(Command* command)
{
p_Commandlist.push_back(command);
cout << "增加烤肉命令" << endl;
}
//按順序執行所有命令
void Waiter::Notify()
{
vector<Command*>::iterator i;
for (i = p_Commandlist.begin(); i < p_Commandlist.end(); ++i)
{
(*i)->ExecuteCommand();
}
}
int main(int argc, char* argv[])
{
//生成訂單,燒烤師傅,服務員
Barbecuer* p_cook = new Barbecuer();
Command* p_mutton = new BakeMuttonCommand(p_cook);
Command* p_chicken = new BakeChickenWingCommand(p_cook);
Waiter* p_waiter = new Waiter();
//將頂點新增到佇列中
p_waiter->SetOrder(p_mutton);
p_waiter->SetOrder(p_chicken);
//服務員通知訂單開始執行
p_waiter->Notify();
SAFE_DELETE(p_cook);
SAFE_DELETE(p_mutton);
SAFE_DELETE(p_chicken);
SAFE_DELETE(p_waiter);
return 0;
}
2.單人回合制的遊戲中,我們想讓玩家能夠撤銷一些行動一邊能夠更多專注與策略而不是猜測。我們可以將所有的動作封裝起來。
虛擬碼如下:
class Command
{
public:
virtual ~Command() {}
virtual void execute() = 0;
virtual void undo() = 0;
};
class MoveUnitCommand : public Command
{
public:
MoveUnitCommand(Unit* unit, int x, int y)
: unit_(unit),
xBefore_(0),
yBefore_(0),
x_(x),
y_(y)
{}
virtual void execute()
{
// 儲存移動之前的位置
// 這樣之後可以復原。
xBefore_ = unit_->x();
yBefore_ = unit_->y();
unit_->moveTo(x_, y_);
}
virtual void undo()
{
unit_->moveTo(xBefore_, yBefore_);
}
private:
Unit* unit_;
int xBefore_, yBefore_;
int x_, y_;
};
參考資料:《遊戲程式設計模式》,《設計模式》
相關文章
- 軟體設計模式學習(十八)命令模式設計模式
- 設計模式學習——代理模式設計模式
- 設計模式-建立型模式學習設計模式
- js設計模式–命令模式JS設計模式
- Java設計模式——命令模式Java設計模式
- js設計模式--命令模式JS設計模式
- Python 設計模式-命令模式Python設計模式
- 設計模式-命令模式(Command)設計模式
- 設計模式之命令模式設計模式
- 設計模式之-命令模式設計模式
- 設計模式學習-裝飾模式,橋接模式設計模式橋接
- 設計模式(一)學習設計模式的好處設計模式
- 學習筆記-設計模式:MVC模式筆記設計模式MVC
- 設計模式快速學習(六)模板模式設計模式
- 設計模式快速學習(八)委派模式設計模式
- 設計模式快速學習(七)策略模式設計模式
- 設計模式學習(十八)中介者模式設計模式
- 設計模式學習之單例模式設計模式單例
- 設計模式系列 6– 命令模式設計模式
- 設計模式實戰 - 命令模式設計模式
- JavaScript設計模式(七):命令模式JavaScript設計模式
- Javascript設計模式之命令模式JavaScript設計模式
- 簡說設計模式——命令模式設計模式
- 極簡設計模式-命令模式設計模式
- Java設計模式(16)----------命令模式Java設計模式
- GoLang設計模式08 - 命令模式Golang設計模式
- FSM 設計模式學習設計模式
- Java設計模式學習筆記(一) 設計模式概述Java設計模式筆記
- [head first 設計模式] 第一章 策略模式設計模式
- 設計模式快速學習(五)原型模式設計模式原型
- 設計模式快速學習(一)工廠模式設計模式
- 設計模式學習之訪問者模式設計模式
- 設計模式快速學習(四)建造者模式設計模式
- 設計模式快速學習(三)單例模式設計模式單例
- 設計模式學習(六)-抽象工廠模式設計模式抽象
- 設計模式學習筆記——單例模式設計模式筆記單例
- JAVA設計模式之 13.命令設計模式Java設計模式
- C#設計模式之命令模式C#設計模式