观察者模式又叫发布/订阅模式,观察者模式定义了一种一对多的依赖关系,让多个观察者对象同时监听某一个主题对象。这个主题对象在状态发生变化时,会通知所有观察者对象,使它们能够自动更新自己。
下面是观察者模式的结构图:
Subject类把所有对观察者对象的引用保存在一个聚集里,,每个主题都可以有任何数量的观察者,抽象主题提供一个接口,可以增加和删除观察者对象。Observer类抽象观察者,为所有的具体观察者定义一个接口,在得到主题的通知时更新自己。ConcreteSubject类具体主题,将有关状态存入具体观察者对象;在具体主题的内部状态改变时,给所有登记过的观察者发出通知;ConcreteObserver类,具体观察者,实现抽象观察者角色所要求的更新接口,以便使本身的状态与主题的状态相协调。
以下是代码例子:
#ifndef __SUBJECT__H__
#define __SUBJECT__H__
#include <string>
using namespace std;
class Observer;
class Subject
{
public:
virtual ~Subject(){}
virtual void Attach(Observer* __o) = 0;
virtual void Detach(Observer* __o) = 0;
virtual void Notify( ) = 0;
virtual string& GetSubjectAction() = 0;
virtual void SetSubjectAction(const string& __s ) = 0;
};
#ifndef __OBSERVER__H__
#define __OBSERVER__H__
#include <string>
using namespace std;
class Subject;
class Observer
{
public:
Observer(string __name, Subject* __sub)
{
m_strName = __name;
m_pSub = __sub;
}
virtual ~Observer()
{
}
virtual void Update() = 0;
protected:
string m_strName;
Subject* m_pSub;
};
#endif // !__OBSERVER__H__
#ifndef __BOSS__H__
#define __BOSS__H__
#include "Observer.h"
#include "Subject.h"
#include <list>
class Boss : public Subject
{
private:
list<Observer*> m_lObervers;
string m_strAction;
public:
virtual void Attach(Observer* __o)
{
m_lObervers.push_back(__o);
}
virtual void Detach(Observer* __o)
{
m_lObervers.remove(__o);
}
virtual void Notify()
{
for (list<Observer*>::iterator it = m_lObervers.begin(); it != m_lObervers.end(); it++)
{
Observer* __o = *it;
__o->Update();
}
}
virtual string& GetSubjectAction()
{
return m_strAction;
}
virtual void SetSubjectAction(const string& __s)
{
m_strAction = __s;
}
};
#endif // !__BOSS
#ifndef __SECRETARY__H__
#define __SECRETARY__H__
#include "Observer.h"
#include "Subject.h"
#include <list>
class Secretary : public Subject
{
private:
list<Observer*> m_lObervers;
string m_strAction;
public:
virtual void Attach(Observer* __o)
{
m_lObervers.push_back(__o);
}
virtual void Detach(Observer* __o)
{
m_lObervers.remove(__o);
}
virtual void Notify()
{
for (list<Observer*>::iterator it = m_lObervers.begin(); it != m_lObervers.end(); it++)
{
Observer* __o = *it;
__o->Update();
}
}
virtual string& GetSubjectAction()
{
return m_strAction;
}
virtual void SetSubjectAction( const string& __s )
{
m_strAction = __s;
}
};
#endif // !__SECRETARY
#ifndef __NBAOBSERVER__H__
#define __NBAOBSERVER__H__
#include "Observer.h"
#include "Subject.h"
#include <stdio.h>
class NBAObserver : public Observer
{
public:
NBAObserver(string __n, Subject* __s) : Observer(__n, __s)
{
}
~NBAObserver()
{
if (m_pSub)
{
delete m_pSub;
m_pSub = NULL;
}
}
virtual void Update()
{
string strRet = m_pSub->GetSubjectAction();
printf("%s %s 关闭股票行情,继续工作!\n", strRet.c_str(), m_strName.c_str());
}
};
#endif // !__NBAOBSERVER__H__
#ifndef __STOCKOBSERVER__H__
#define __STOCKOBSERVER__H__
#include "Observer.h"
#include "Subject.h"
#include <stdio.h>
class StockObserver : public Observer
{
public:
StockObserver(string __n, Subject* __s) : Observer(__n, __s)
{
}
~StockObserver()
{
if (m_pSub)
{
delete m_pSub;
m_pSub = NULL;
}
}
virtual void Update()
{
printf("%s %s 关闭股票行情,继续工作!\n", m_pSub->GetSubjectAction().c_str(), m_strName.c_str() );
}
};
#endif //!__STOCKOBSERVER
//客户端代码
#include <windows.h>
#include <tchar.h>
#include "NBAObserver.h"
#include "StockObserver.h"
#include "Boss.h"
#include "Secretary.h"
int _tmain(int argc, TCHAR* argv[])
{
//未利用委托
Boss *pbWang = new Boss();
Observer * pStock = new StockObserver("Mr Wang", pbWang);
Observer * pNBA = new NBAObserver("Mrs Yu", pbWang);
pbWang->Attach(pStock);
pbWang->Attach(pNBA);
pbWang->SetSubjectAction("Boss Mr Wang come back");
pbWang->Notify();
printf("\n\n*****************\n\n");
pbWang->Detach(pStock);
pbWang->Notify();
if (pbWang)
{
delete pbWang;
pbWang = NULL;
}
//利用委托
return 0;
}
运行结果: