Observer模式定义对象间的一对多的依赖关系,当一个对象的状态发生改变时,所有依赖于它的对象都得到通知并被自动更新。
Subject类一般都是采用链表等容器来存放Observer对象指针;
Observer类一般是抽取Observer对象的一些公共的属性形成Observer基类,而Subject中保存的则是Observer类对象的指针,这样就使Subject和具体的Observer实现了解耦;
下面是测试代码:
#ifndef OBSERVER_H
#define OBSERVER_H
#include <list>
#include <pthread.h>
using namespace std;
typedef int STATUS;
#define SAFE_DELETE(p) { if(p) { delete (p); (p)=NULL; } }
#define SAFE_DELETE_ARRAY(p) { if(p) { delete[] (p); (p)=NULL; } }
class Mutex
{
public:
Mutex()
{
pthread_mutex_init(&m_lock,NULL);
}
~Mutex()
{
pthread_mutex_destroy(&m_lock);
}
void Lock()
{
pthread_mutex_lock(&m_lock);
}
void UnLock()
{
pthread_mutex_unlock(&m_lock);
}
private:
pthread_mutex_t m_lock;
};
class IObserver;
class ISubject
{
public:
ISubject() : m_statusSubject(-1) {}
virtual ~ISubject();
void Register(IObserver *pObserver);
void UnRegister(IObserver *pObserver);
virtual void SetStatus(STATUS status) = 0;
virtual STATUS GetStatus() = 0;
virtual void Notify() = 0;
protected:
STATUS m_statusSubject;
Mutex m_mutex;
list<IObserver*> m_listObserver;
};
class Subject : public ISubject
{
public:
Subject() {}
virtual ~Subject() {};
virtual void SetStatus(STATUS status);
virtual STATUS GetStatus();
virtual void Notify();
};
class IObserver
{
public:
IObserver() : m_statusObserver(-1) {}
virtual ~IObserver() {}
virtual void Update(ISubject* pSubject) = 0;
protected:
STATUS m_statusObserver;
};
class Observer : public IObserver
{
public:
Observer() {}
virtual ~Observer() {}
virtual void Update(ISubject* pSubject);
};
#endif
#include "Observer.h"
#include <stdio.h>
#include <algorithm>
ISubject::~ISubject()
{
m_mutex.Lock();
m_listObserver.clear();
m_mutex.UnLock();
printf("--- Subject clear \n");
}
void ISubject::Register(IObserver *pObserver)
{
m_mutex.Lock();
m_listObserver.push_back(pObserver);
m_mutex.UnLock();
printf("+ Register one observer. \n");
}
void ISubject::UnRegister(IObserver *pObserver)
{
m_mutex.Lock();
list<IObserver*>::iterator iter = find(m_listObserver.begin(), m_listObserver.end(), pObserver);
if (m_listObserver.end() != iter)
{
m_listObserver.erase(iter);
}
m_mutex.UnLock();
printf("- UnRegister one observer. \n");
}
void Subject::Notify()
{
m_mutex.Lock();
for (std::list<IObserver*>::iterator iter = m_listObserver.begin(); iter != m_listObserver.end(); ++iter)
{
(*iter)->Update(this);
}
m_mutex.UnLock();
printf("<<< Notify all observers. \n");
}
void Subject::SetStatus(STATUS status)
{
m_statusSubject = status;
printf("SetStatus m_statusSubject=%d. \n", m_statusSubject);
}
STATUS Subject::GetStatus()
{
printf("GetStatus m_statusSubject=%d. \n", m_statusSubject);
return m_statusSubject;
}
void Observer::Update(ISubject *pSubject)
{
if (NULL == pSubject)
{
return;
}
m_statusObserver = pSubject->GetStatus();
}
int main()
{
IObserver *pObA = new Observer;
IObserver *pObB = new Observer;
IObserver *pObC = new Observer;
ISubject *pSub = new Subject;
pSub->Register(pObA);
pSub->Register(pObB);
pSub->Register(pObC);
pSub->SetStatus(1);
pSub->Notify();
pSub->UnRegister(pObA);
pSub->UnRegister(pObB);
pSub->SetStatus(2);
pSub->Notify();
SAFE_DELETE(pSub);
SAFE_DELETE(pObA);
SAFE_DELETE(pObB);
SAFE_DELETE(pObC);
return 0;
}