觀察者模式又叫發佈/訂閱模式,觀察者模式定義了一種一對多的依賴關係,讓多個觀察者對象同時監聽某一個主題對象。這個主題對象在狀態發生變化時,會通知所有觀察者對象,使它們能夠自動更新自己。
下面是觀察者模式的結構圖:
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;
}
運行結果: