设计模式--观察者模式
设计模式 -- Observer 观察者模式
模式定义
定义对象间的一种一对多(变化)的依赖关系,以便当一个对象(Subject)的状态发生改变时,所有依赖于它的对象都得到通知并自动更新。
——《设计模式》GoF
动机(Motivation)
- 在软件构建过程中,我们需要为某些对象建立一种“通知依赖关
 系” ——一个对象(目标对象)的状态发生改变,所有的依赖对
 象(观察者对象)都将得到通知。如果这样的依赖关系过于紧密,
 将使软件不能很好地抵御变化。
- 使用面向对象技术,可以将这种依赖关系弱化,并形成一种稳定
 的依赖关系。从而实现软件体系结构的松耦合。
结构(Structure)

要点总结
- 使用面向对象的抽象,Observer模式使得我们可以独立地改变目
 标与观察者,从而使二者之间的依赖关系达致松耦合。
- 目标发送通知时,无需指定观察者,通知(可以携带通知信息作
 为参数)会自动传播。
- 观察者自己决定是否需要订阅通知,目标对象对此一无所知。
- Observer模式是基于事件的UI框架中非常常用的设计模式,也是
 MVC模式的一个重要组成部分。
实战代码
#include <iostream>
#include <list>
#include <string>
/*
					观察者模式
	定义对象间的一种一对多(变化)的依赖关系,以便当一个
	对象(Subject)的状态发生改变时,所有依赖于它的对象都
	得到通知并自动更新。
									——《设计模式》GoF
*/
using namespace std;
class Observer
{
public:
	Observer() { ; }
	virtual ~Observer() { ; }
	// 当被观察对象发生变化时,通知被观察者调用这个方法
	virtual void Update(void* pArg) = 0;
};
class User1 : public Observer
{
public:
	virtual void Update(void* pArg)
	{
		cout << "User1:" << (char *)pArg << endl;
	}
};
class User2 : public Observer
{
public:
	virtual void Update(void* pArg)
	{
		cout << "User2:" << (char *)pArg << endl;
		//reinterpret_cast
	}
};
class Observerable
{
public:
	Observerable() :_bChange(false)
	{
	}
	virtual ~Observerable() {}
	// 注册观察者
	void Attach(Observer* pOb)
	{
		_Obs.push_back(pOb);
	}
	// 反注册观察者
	void Detach(Observer* pOb)
	{
		_Obs.remove(pOb);
	}
	int GetObseverCount() const
	{
		return _Obs.size();
	}
	void DetachAll()
	{
		_Obs.clear();
	}
	virtual void GetSomeNews(string str)
	{
		SetChange(str);
	}
protected:
	void  SetChange(string news)   // 有变化,需要通知
	{
		_bChange = true;
		Notify((void*)news.c_str());
	}
private:
	void Notify(void* pArg)
	{
		if (_bChange == false) return;
		//遍历容器
		for (auto itr = _Obs.begin(); itr != _Obs.end(); itr++)
			(*itr)->Update(pArg);//遍历调用list容器里面子类的虚函数Update,实现各个子类的运行多态
		_bChange = false;
	}
private:
	bool _bChange;
	list<Observer*> _Obs;
};
class News : public Observerable
{
public:
	virtual void GetSomeNews(string str)
	{
		SetChange("News: " + str);
	}
};
int main()
{
	User1 u1;
	User2 u2;
	News n1;
	n1.GetSomeNews("T0");//发送广播
	cout << n1.GetObseverCount() << endl;  // 0
	n1.Attach(&u1);
	n1.Attach(&u2);
	n1.GetSomeNews("T1");
	cout << n1.GetObseverCount() << endl;  // 2
	n1.Detach(&u2);
	n1.GetSomeNews("T2");
	cout << n1.GetObseverCount() << endl;  // 1
	n1.DetachAll();
	n1.GetSomeNews("T3");
	cout << n1.GetObseverCount() << endl;  // 0
	return 0;
}
运行结果


 
                
            
         
         浙公网安备 33010602011771号
浙公网安备 33010602011771号