设计模式之观察者模式

1. 观察者模式

1.1 什么是观察者模式

​ 观察者一般可以看做是第三者,比如在学校上自习的时候,大家肯定都有过交头接耳、各种玩耍的经历,这时总会有一个“放风”的小伙伴,当老师即将出现时及时“通知”大家老师来了。再比如,拍卖会的时候,大家相互叫价,拍卖师会观察最高标价,然后通知给其它竞价者竞价,这就是一个观察者模式。

  观察者模式(Observer),又叫发布-订阅模式(Publish/Subscribe),定义对象间一种一对多的依赖关系,使得每当一个对象改变状态,则所有依赖于它的对象都会得到通知并自动更新。UML结构图如下:

image-20210723123301754

观察者模式:观察者模式中存在着主题与观察者,如果观察者观察某个主题,那么一旦主题发生变化,就会通知所有的观察者

简单来说,就是通过在主题类里面创建一个观察者列表,然后添加观察者,当事件发生的时候,通过遍历来通知所有的观察者!

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 运行结果

image-20210723134236186

可以看到,英雄一移动,公主和怪物都做出了相应的相应!

posted @ 2021-07-23 14:43  进击的汪sir  阅读(457)  评论(0编辑  收藏  举报