设计模式--观察者模式

设计模式 -- 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;
}

运行结果

posted @ 2020-08-03 14:18  MCreator  阅读(156)  评论(1编辑  收藏  举报