观察者模式(行为型模式)

概念

Observer模式是行为模式之一,它的作用是当一个对象的状态发生变化时,能够自动通知其他关联对象,自动刷新对象状态。

Observer模式提供给关联对象一种同步通信的手段,使某个对象与依赖它的其他对象之间保持状态同步。

角色和职责

Subject(被观察者)
         被观察的对象。当需要被观察的状态发生变化时,需要通知队列中所有观察者对象。Subject需要维持(添加,删除,通知)一个观察者对象的队列列表。

ConcreteSubject
         被观察者的具体实现。包含一些基本的属性状态及其他操作。

Observer(观察者)
         接口或抽象类。当Subject的状态发生变化时,Observer对象将通过一个callback函数得到通知。

ConcreteObserver
         观察者的具体实现。得到通知后将完成一些具体的业务逻辑处理。

意图

定义对象间的一种一对多的依赖关系,当一个对象的状态发生改变时,所有依赖于它的对象都得到通知并被自动更新。

主要解决

一个对象状态改变给其他对象通知的问题,而且要考虑到易用和低耦合,保证高度的协作。

何时使用

一个对象(目标对象)的状态发生改变,所有的依赖对象(观察者对象)都将得到通知,进行广播通知。

如何解决

使用面向对象技术,可以将这种依赖关系弱化。

关键代码

在抽象类里有一个 ArrayList 存放观察者们。

应用实例

拍卖的时候,拍卖师观察最高标价,然后通知给其他竞价者竞价
西游记里面悟空请求菩萨降服红孩儿,菩萨洒了一地水招来一个老乌龟,这个乌龟就是观察者,他观察菩萨洒水这个动作。

优点

观察者和被观察者是抽象耦合的
建立一套触发机制


缺点

如果一个被观察者对象有很多的直接和间接的观察者的话,将所有的观察者都通知到会花费很多时间
如果在观察者和观察目标之间有循环依赖的话,观察目标会触发它们之间进行循环调用,可能导致系统崩溃
观察者模式没有相应的机制让观察者知道所观察的目标对象是怎么发生变化的,而仅仅只是知道观察目标发生了变化


使用场景

一个抽象模型有两个方面,其中一个方面依赖于另一个方面。将这些方面封装在独立的对象中使它们可以各自独立地改变和复用。 
一个对象的改变将导致其他一个或多个对象也发生改变,而不知道具体有多少对象将发生改变,可以降低对象之间的耦合度。 
一个对象必须通知其他对象,而并不知道这些对象是谁。 
需要在系统中创建一个触发链,A对象的行为将影响B对象,B对象的行为将影响C对象……,可以使用观察者模式创建一种链式触发机制。

典型应用

- 侦听事件驱动程序设计中的外部事件

- 侦听/监视某个对象的状态变化

- 发布者/订阅者(publisher/subscriber)模型中,当一个外部事件(新的产品,消息的出现等等)被触发时,通知邮件列表中的订阅者

适用于:

定义对象间一种一对多的依赖关系,使得每一个对象改变状态,则所有依赖于他们的对象都会得到通知。

使用场景:定义了一种一对多的关系,让多个观察对象(公司员工)同时监听一个主题对象(秘书),主题对象状态发生变化时,会通知所有的观察者,使它们能够更新自己。

简单案例:

英雄打怪兽:

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

/*观察者模式
*一个对象状态的改变会触发一组对象状态的改变
*/

//游戏中,英雄打BOSS

//抽象的英雄-》观察者
class AbstractHero{
public:
	//更新英雄的状态
	virtual void update() = 0;
};

//具体的英雄
class HeroA :public AbstractHero{
public:
	HeroA(){
		cout << "英雄A正在打BOSS!!!" << endl;
	}
	virtual void update(){
		cout << "BOSS阵亡,英雄A待机状态" << endl;
	}
};

class HeroB :public AbstractHero{
public:
	HeroB(){
		cout << "英雄B正在打BOSS!!!" << endl;
	}
	virtual void update(){
		cout << "BOSS阵亡,英雄B待机状态" << endl;
	}
};

class HeroC :public AbstractHero{
public:
	HeroC(){
		cout << "英雄C正在打BOSS!!!" << endl;
	}
	virtual void update(){
		cout << "BOSS阵亡,英雄C待机状态" << endl;
	}
};

class HeroD :public AbstractHero{
public:
	HeroD(){
		cout << "英雄D正在打BOSS!!!" << endl;
	}
	virtual void update(){
		cout << "BOSS阵亡,英雄D待机状态" << endl;
	}
};

//抽象的观察目标
class AbstractBoss{
public:
	//添加观察者
	virtual void addHero(AbstractHero *h) = 0;
	//删除观察者
	virtual void deleteHero(AbstractHero *h) = 0;
	//通知观察者
	virtual void notify() = 0;
};

//观察目标
class BOSS: public AbstractBoss{
public:
	virtual void addHero(AbstractHero* h){
		hero.push_back(h);
	}

	virtual void deleteHero(AbstractHero* h){
		hero.remove(h); //删除容器中所有值等于h的
	}

	virtual void notify(){
		for (list<AbstractHero* >::iterator it = hero.begin();
			it != hero.end(); it++){
			(*it)->update();
		}
	}
private:
	list<AbstractHero* > hero;
};

void test(){

	//观察者
	AbstractHero* ha = new HeroA;
	AbstractHero* hb = new HeroB;
	AbstractHero* hc = new HeroC;
	AbstractHero* hd = new HeroD;

	//观察目标
	AbstractBoss* boss = new BOSS;
	boss->addHero(ha);
	boss->addHero(hb);
	boss->addHero(hc);
	boss->addHero(hd);

	//场景模拟——》D阵亡
	boss->deleteHero(hd);

	cout << "BOSS阵亡,通知其他英雄。。。。" << endl;

	boss->notify();
}

int main(void){
	test();
	return 0;
}
发布了178 篇原创文章 · 获赞 15 · 访问量 1万+

猜你喜欢

转载自blog.csdn.net/weixin_42067873/article/details/105577940