1. 觀察者模式
1.1 什么是觀察者模式
觀察者一般可以看做是第三者,比如在學校上自習的時候,大家肯定都有過交頭接耳、各種玩耍的經歷,這時總會有一個“放風”的小伙伴,當老師即將出現時及時“通知”大家老師來了。再比如,拍賣會的時候,大家相互叫價,拍賣師會觀察最高標價,然后通知給其它競價者競價,這就是一個觀察者模式。
觀察者模式(Observer),又叫發布-訂閱模式(Publish/Subscribe),定義對象間一種一對多的依賴關系,使得每當一個對象改變狀態,則所有依賴於它的對象都會得到通知並自動更新。UML結構圖如下:
觀察者模式:觀察者模式中存在着主題與觀察者,如果觀察者觀察某個主題,那么一旦主題發生變化,就會通知所有的觀察者
簡單來說,就是通過在主題類里面創建一個觀察者列表,然后添加觀察者,當事件發生的時候,通過遍歷來通知所有的觀察者!
1.2 實例理解
很多東西,其實對於我們程序員來說,往往是代碼更有說服力
因此我們通過一個實例來理解
說一個故事,,,很久很久以前,一個英雄去救公主,那么關注英雄的人有兩個,一個是怪物monster,一個是公主princess,那么每當英雄向着怪物移動的時候,怪物和公主都有不同的反應,怪物會說:你不要過來啊!公主會說:我在這,快來救我!
下面我們通過觀察者模式來復原這個故事!
首先實現觀察者的抽象類Observer
代碼如下
/////////////我的博客//////////////
static string MyBlog = "https://www.cnblogs.com/wanghongyang";
/////////////我的博客//////////////
class Observer {
public:
virtual void update() = 0;
};
定義了一個純虛函數upadate()
然后定義怪物類與公主類,繼承觀察者的抽象類
class Monster : public Observer {
public:
void update() {
cout << "Monster: " << "你不要過來啊!!!" << endl;
}
};
class Princess : public Observer {
public:
void update() {
cout << "Princess: " << "我在這,快過來救我" << endl;
}
};
實現了定義的純虛函數update()
然后定義英雄類Hero,對應着觀察者模式中的主題
class Hero
{
private:
vector<Observer*> obList;
public:
void addObserver(Observer* observer) {
obList.push_back(observer);
}
void removeObserver(Observer* observer) {
for (vector<Observer*>::iterator it = obList.begin(); it != obList.end(); it++) {
if (*it = observer) {
obList.erase(it);
}
}
}
void move() {
cout << "hero: " << "正在朝着怪物移動!" << endl;
//for(int i=0;i<obList.size();i++)
for (auto ob : obList) {
ob->update();
}
}
};
里面有三個方法
- addObserver:增加觀察者
- removeObserver:移除觀察者
- move:代表英雄移動,需要通知所有的觀察者
最后實現主函數
int main() {
// 公主和怪獸就是觀察者,觀察英雄,英雄對應着主題
Hero hero;
Monster mons;
Princess prin;
// 添加觀察者
hero.addObserver(&mons);
hero.addObserver(&prin);
// 英雄移動
hero.move();
cout << "原創博主: 進擊的汪sir https://www.cnblogs.com/wanghongyang" << endl;
return 0;
}
1.3 運行結果
可以看到,英雄一移動,公主和怪物都做出了相應的相應!