Observer.h
#ifndef _OBSERVER_H_
#define _OBSERVER_H_
#include "Subject.h"
#include <string>
using namespace std;
typedef string State;
class CConcreteObserverA:public CObserver
{
public:
CConcreteObserverA(CSubject *sub);
~CConcreteObserverA();
void Update(CSubject *sub);
void PrintInfo();
CSubject*GetSubject();
private:
CSubject *m_Sub;
};
class CConcreteObserverB:public CObserver
{
public:
CConcreteObserverB(CSubject *sub);
~CConcreteObserverB();
void Update(CSubject *sub);
void PrintInfo();
CSubject*GetSubject();
private:
CSubject *m_Sub;
};
#endif
Observer.cpp
#include <iostream>
#include "Observer.h"
using namespace std;
CObserver::CObserver()
{
m_State="\0";
}
CObserver::~CObserver()
{
}
CConcreteObserverA::CConcreteObserverA(CSubject *sub)
{
m_Sub=sub;
m_Sub->Attach(this);
}
CConcreteObserverA::~CConcreteObserverA()
{
if(m_Sub)
{
m_Sub->Detach(this);
delete m_Sub;
m_Sub=0;
}
}
CSubject *CConcreteObserverA::GetSubject()
{
return m_Sub;
}
void CConcreteObserverA::PrintInfo()
{
cout<<"CConcreteObserverA:"<<m_Sub->GetState()<<endl;
}
void CConcreteObserverA::Update(CSubject *sub)
{
m_State=sub->GetState();
PrintInfo();
}
///
CConcreteObserverB::CConcreteObserverB(CSubject *sub)
{
m_Sub=sub;
m_Sub->Attach(this);
}
CConcreteObserverB::~CConcreteObserverB()
{
if(m_Sub)
{
m_Sub->Detach(this);
delete m_Sub;
m_Sub=0;
}
}
CSubject *CConcreteObserverB::GetSubject()
{
return m_Sub;
}
void CConcreteObserverB::PrintInfo()
{
cout<<"CConcreteObserverB:"<<m_Sub->GetState()<<endl;
}
void CConcreteObserverB::Update(CSubject *sub)
{
m_State=sub->GetState();
PrintInfo();
}
Subject.h
#ifndef _SUBJECT_H_
#define _SUBJECT_H_
#include <list>
#include <string>
using namespace std;
typedef string State;
class CObserver;
class CSubject
{
public:
CSubject();
virtual ~CSubject();
virtual void Attach(CObserver *obv);
virtual void Detach(CObserver *obv);
virtual void Notify();
virtual void SetState(const State& st)=0;
virtual State GetState()=0;
private:
list<CObserver*>*_obv;
};
class CObserver
{
public:
CObserver();
virtual ~CObserver();
virtual CSubject*GetSubject()=0;
virtual void Update(CSubject *sub)=0;
virtual void PrintInfo()=0;
protected:
State m_State;
};
class CConcerteCSubject:public CSubject
{
public:
CConcerteCSubject();
~CConcerteCSubject();
void SetState(const State& st);
State GetState();
private:
State m_State;
};
#endif
Subject.cpp
#include "Subject.h"
CSubject::CSubject()
{
_obv=new list<CObserver*>;
}
CSubject::~CSubject()
{
if(_obv)
{
delete _obv;
_obv=0;
}
}
void CSubject::Attach(CObserver *obv)
{
if(obv)
_obv->push_front(obv);
}
void CSubject::Detach(CObserver *obv)
{
if(obv)
{
_obv->remove(obv);
}
}
void CSubject::Notify()
{
list<CObserver*>::iterator it;
it=_obv->begin();
for(; it != _obv->end(); ++it)
{
(*it)->Update(this);
}
}
CConcerteCSubject::CConcerteCSubject()
{
m_State="\0";
}
CConcerteCSubject::~CConcerteCSubject()
{
}
State CConcerteCSubject::GetState()
{
return m_State;
}
void CConcerteCSubject::SetState(const State &st)
{
m_State=st;
}
Main.cpp
#include <iostream>
#include "Observer.h"
#include "Subject.h"
using namespace std;
int main() //Client
{
CConcerteCSubject *sub = new CConcerteCSubject();
CObserver *o1 = new CConcreteObserverA(sub);
CObserver *o2 = new CConcreteObserverB(sub);
sub->SetState("old");
sub->Notify();
sub->SetState("New");
sub->Notify();
return 0;
}
在Observer模式的实现中,Subject维护一个list作为存储其所有观察者的容器。每当
调用Notify操作就遍历list中的Observer对象,并广播通知改变状态(调用Observer的Update操作)。目标的状态state可以由Subject自己改变(示例),也可以由Observer的某个操作引起state的改变(可调用Subject的SetState操作)。Notify操作可以由Subject目标主动广播(示例),也可以由Observer观察者来调用(因为Observer维护一个指向Subject的指针)。
运行示例程序,可以看到当Subject处于状态“old”时候,依赖于它的两个观察者都显示“old”,当目标状态改变为“new”的时候,依赖于它的两个观察者也都改变为“new”。