用C++跟你聊聊“命令模式”,跟我聊就夠了

在這裏插入圖片描述

預約“大牌”的困擾

我有一個朋友,他是個大忙人,每天的行程表都是塞得滿滿的,要預約他可不容易。關鍵是,剛開始他還是邋里邋遢的,並沒有一個明確的日程表。這就導致了三個問題:

1、我們不知道什麼時候可以約他,就只能直接把預約請求扔給他。
2、他有時候都不知道回覆我們的預約,有時候預約了他又忘記了,忙嘛。
3、我們不方便單方面解約,畢竟人家百忙之中還抽空出來嘛。

後來,他有了祕書。
1、我們預約他,給他的祕書說一下就好。
2、他的祕書會提醒他佳人有約。
3、我們要取消約定,跟他的祕書說一下就好了。

真是大牌,祕書都用上了。

這裏又隱藏着一個設計模式 – 命令模式

命令模式

命令模式:將一個請求封裝成一個對象,從而可以使你用不同的請求對客戶進行參數化、對請求排隊或記錄請求日誌、以及支持可撤銷的操作。

在這裏插入圖片描述
上面這圖可能抽象了點啊,沒事兒,咱不是有故事嘛。
再來一張就是了。

在這裏插入圖片描述

小故事的代碼完整實現

這裏囊括瞭解約、記錄、針對不同任務等模塊,我在網上其他地方是沒找到用C++有實現這個的。

#include<iostream>
#include<list>
using namespace std;

//大忙人類
class BusyMan {
public:
	void Dinner() { cout << "晚餐" << endl; }
	void Game() { cout << "打遊戲" << endl; }
};


//抽象命令類
class AbsCommand {
protected :
	BusyMan *man;
	string state;	//命令參數
public:
	AbsCommand(BusyMan* man) { this->man = man; }

	string getState() { return state; }
	//執行命令
	virtual void excuteCommand() = 0;
};

//吃晚飯預約
class DinnerCommand :public AbsCommand {
public:
	DinnerCommand(BusyMan* man) :AbsCommand(man) { this->state = "晚飯"; };
	void excuteCommand() {
		man->Dinner();
	}
};

//打遊戲預約
class GameCommand :public AbsCommand {
public:
	GameCommand(BusyMan* man) :AbsCommand(man) { this->state = "打遊戲"; };
	void excuteCommand() {
		man->Game();
	}
};

//祕書類
class selary {
private:
	list<AbsCommand*> AC;

public:
	//安排預約
	void SetOrder(AbsCommand* abs) {
		if (abs->getState() == "晚飯")
			cout << "沒空" << endl;
		else
		{
			AC.push_back(abs);
			cout << "預約成功,請於XX:XX準時上線快樂雙排" << endl;

			//這裏可以再加個寫入配置文件的
		}
	}

	//解約
	void cancelOrder(AbsCommand* abs){
		AC.remove(abs);
		cout << "解約成功" << endl;
	}

	void notify(){
		list<AbsCommand*>::iterator it = AC.begin();
		while (it != AC.end())
		{
			(*it)->excuteCommand();
			it++;
		}
		AC.clear();
	}
};


int main()
{
	BusyMan* man = new BusyMan();

	AbsCommand* d = new DinnerCommand(man);
	AbsCommand* g1 = new GameCommand(man);
	AbsCommand* g2 = new GameCommand(man);

	selary* s = new selary();

	s->SetOrder(d);
	s->SetOrder(g1);
	s->notify();

	s->SetOrder(g1);
	s->SetOrder(g2);
	s->cancelOrder(g1);
	s->notify();
	return 0;
}

應用場景

命令模式通常適用於以下場景。

 當系統需要將請求調用者與請求接收者解耦時,命令模式使得調用者和接收者不直接交互。
    當系統需要隨機請求命令或經常增加或刪除命令時,命令模式比較方便實現這些功能。
    當系統需要執行一組操作時,命令模式可以定義宏命令來實現該功能。
    當系統需要支持命令的撤銷(Undo)操作和恢復(Redo)操作時,可以將命令對象存儲起來,採用備忘錄模式來實現。
發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章