定义:观察者模式(发布/订阅模式,模型(Model)-视图(View)模式、源-收听者(Listener)模式或从属者模式,属于行为模式中的一种,定义对象间的一种一对多的依赖关系,当一个对象的状态发生改变时,所有依赖于它的对象都得到通知并被自动更新。

当一个对象发生了变化,关注它的对象就会得到通知;这种交互也称为发布-订阅(publish-subscribe)。目标是通知的发布者,它发出通知时并不需要知道谁是它的观察者。

举例
对同一组数据进行统计分析时候, 我们希望能够提供多种形式的表示 (例如以表格进行统计显示、柱状图统计显示、百分比统计显示等)。这些表示都依赖于同一组数据, 我们当然需要当数据改变的时候, 所有的统计的显示都能够同时改变。

角色

  • 抽象主题(Subject):该角色是一个抽象类或接口,定义了增加、删除、通知观察者对象的方法。
  • 具体主题(ConcreteSubject):该角色继承或实现了抽象主题,定义了一个集合存入注册过的具体观察者对象,在具体主题的内部状态发生改变时,给所有注册过的观察者发送通知。
  • 抽象观察者(Observer):该角色是具体观察者的抽象类,定义了一个更新方法。
  • 具体观察者(ConcrereObserver):该角色是具体的观察者对象,在得到具体主题更改通知时更新自身的状态。

代码示例:

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

class Observer  //抽象观察者
{
public:
	virtual void Update(int) = 0;
};

class Subject  //抽象目标
{
public:
	virtual void Attach(Observer*) = 0;
	virtual void Detach(Observer*) = 0;
	virtual void Notify() = 0;
};

class ConcreteObserver : public Observer//具体观察者
{
public:
	ConcreteObserver(Subject* pSubject) : m_pSubject(pSubject) {}

	void Update(int value)
	{
		cout << "ConcreteObserver get the update. New State is:" << value << endl;
	}

private:
	Subject* m_pSubject;
};

class ConcreteObserver2 : public Observer
{
public:
	ConcreteObserver2(Subject* pSubject) : m_pSubject(pSubject) {}

	void Update(int value)
	{
		cout << "ConcreteObserver2 get the update. New State is:" << value << endl;
	}

private:
	Subject* m_pSubject;
};

class ConcreteSubject : public Subject//具体目标
{
public:
	void Attach(Observer* pObserver);
	void Detach(Observer* pObserver);
	void Notify();

	void SetState(int state)
	{
		m_iState = state;
	}

private:
	list<Observer*> m_ObserverList;
	int m_iState;
};

void ConcreteSubject::Attach(Observer* pObserver)//将观察者添加到容器中
{
	m_ObserverList.push_back(pObserver);
}

void ConcreteSubject::Detach(Observer* pObserver)//将观察者从容器中删除
{
	m_ObserverList.remove(pObserver);
}

void ConcreteSubject::Notify()//通知容器中的每一个观察者
{
	std::list<Observer*>::iterator it = m_ObserverList.begin();
	while (it != m_ObserverList.end())
	{
		(*it)->Update(m_iState);
		++it;
	}
}

int main()
{
	
	ConcreteSubject* pSubject = new ConcreteSubject();//创建具体的目标

	
	Observer* pObserver = new ConcreteObserver(pSubject);//创建观察者对象
	Observer* pObserver2 = new ConcreteObserver2(pSubject);//创建观察者对象2


	pSubject->SetState(2);//设置目标状态


	pSubject->Attach(pObserver);//将观察者注册到容器中
	pSubject->Attach(pObserver2);

	pSubject->Notify();//通知所有的观察者

	
	pSubject->Detach(pObserver);//删除观察者pObserver

	pSubject->SetState(3);//更新目标状态
	pSubject->Notify();//再次通知所有的观察者,此时容器中只有观察者pObserver2

	delete pObserver;
	delete pObserver2;
	delete pSubject;
}

C++设计模式—观察者模式

具体应用示例

#include <iostream>
#include <string>
#include <list>
using namespace std;

class Subject;
//抽象观察者
class Observer
{
protected:
	string name;
	Subject* sub;
public:
	Observer(string name, Subject* sub)
	{
		this->name = name;
		this->sub = sub;
	}
	virtual void update() = 0;
};

//具体的观察者,看股票的
class StockObserver :public Observer
{
public:
	StockObserver(string name, Subject* sub) :Observer(name, sub)
	{
	}
	void update();
};
//具体的观察者,看NBA的
class NBAObserver :public Observer
{
public:
	NBAObserver(string name, Subject* sub) :Observer(name, sub)
	{
	}
	void update();
};
//抽象通知者
class Subject
{
protected:
	list<Observer*> observers;
public:
	string action;
	virtual void attach(Observer*) = 0;
	virtual void detach(Observer*) = 0;
	virtual void notify() = 0;
};
//具体通知者,秘书
class Secretary :public Subject
{
	void attach(Observer* observer)
	{
		observers.push_back(observer);
	}
	void detach(Observer* observer)
	{
		list<Observer*>::iterator iter = observers.begin();
		while (iter != observers.end())
		{
			if ((*iter) == observer)
			{
				observers.erase(iter);
			}
			++iter;
		}
	}
	void notify()
	{
		list<Observer*>::iterator iter = observers.begin();
		while (iter != observers.end())
		{
			(*iter)->update();
			++iter;
		}
	}
};

void StockObserver::update()
{
	cout << name << " 收到消息:" << sub->action << endl;
	if (sub->action == "领导来了!")
	{
		cout << "我马上关闭股票,装做很认真工作的样子!" << endl;
	}
}

void NBAObserver::update()
{
	cout << name << " 收到消息:" << sub->action << endl;
	if (sub->action == "领导来了!")
	{
		cout << "我马上关闭NBA,装做很认真工作的样子!" << endl;
	}
}



int main()
{
	Subject* se = new Secretary(); //创建观察者    //被观察的对象
	Observer* o1= new NBAObserver("zhangsan", se);
	Observer* o2 = new NBAObserver("lisi", se);
	Observer* lm = new StockObserver("limin", se);
	//加入观察队列
    se->attach(o1);
	se->attach(o2);
	se->attach(lm);
	//事件
	se->action = "去吃饭了!"; 
	se->notify();
	cout << endl;
	
	se->action = "领导来了!";
	se->notify();
	return 0;
}

C++设计模式—观察者模式
适用场合

  • 当一个抽象模型有两个方面,其中一个方面依赖于另一方面。将这二者封装在独立的对象中以使它们可以各自独立的改变和复用。
  • 当对一个对象的改变需要同时改变其它对象,而不知道具体有多少对象有待改变。
  • 当一个对象必须通知其它对象,而它又不能假定其它对象是谁。也就是说,你不希望这些对象是紧密耦合的。

相关文章:

  • 2018-11-02
  • 2019-08-05
  • 2021-11-29
  • 2021-08-05
  • 2019-10-31
  • 2021-09-30
猜你喜欢
  • 2021-08-05
  • 2021-08-05
  • 2021-09-28
  • 2021-08-05
  • 2021-10-04
  • 2021-08-05
  • 2018-03-24
相关资源
相似解决方案