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 运行结果
可以看到,英雄一移动,公主和怪物都做出了相应的相应!