观察者模式定义了对象间一对多的依赖关系,一个目标可以有任意数目的与之相依赖的观察者,一旦观察目标的状态发生改变,所有的观察者都将得到通知。
observer.h
#include <string>
#include <stdio.h>
class CSubject;
class CObserver
{
public:
CObserver(){}
virtual ~CObserver(){}
virtual void Update(CSubject* apoSubject) = 0;
};
class CConcreteObserverA : public CObserver
{
public:
CConcreteObserverA(CSubject* apoSubject);
virtual ~CConcreteObserverA(){}
void Update(CSubject* apoSubject);
private:
CSubject* mpoSubject;
std::string moState;
};
class CConcreteObserverB : public CObserver
{
public:
CConcreteObserverB(CSubject* apoSubject);
virtual ~CConcreteObserverB(){}
void Update(CSubject* apoSubject);
private:
CSubject* mpoSubject;
std::string moState;
};
observer.cpp
#include "observer.h"
#include "subject.h"
CConcreteObserverA::CConcreteObserverA(CSubject* apoSubject)
{
mpoSubject = apoSubject;
apoSubject->Attach(this);
}
void CConcreteObserverA::Update(CSubject* apoSubject)
{
moState = apoSubject->GetState();
printf("state %s\n", moState.c_str());
}
CConcreteObserverB::CConcreteObserverB(CSubject* apoSubject)
{
mpoSubject = apoSubject;
apoSubject->Attach(this);
}
void CConcreteObserverB::Update(CSubject* apoSubject)
{
moState = apoSubject->GetState();
printf("state %s\n", moState.c_str());
}
subject.h
#include <string>
#include <list>
class CObserver;
class CSubject
{
public:
CSubject(){}
virtual ~CSubject(){}
virtual void SetState(std::string aoState) = 0;
virtual std::string GetState() = 0;
void Attach(CObserver* apoObserver);
void Dettach(CObserver* apoObserver);
void Notify();
private:
std::list<CObserver*> moObserverList;
};
class CConcreteSubjectA : public CSubject
{
public:
CConcreteSubjectA(){}
virtual ~CConcreteSubjectA(){}
void SetState(std::string aoState);
std::string GetState();
private:
std::string moState;
};
subject.cpp
#include "subject.h"
#include "observer.h"
void CSubject::Attach(CObserver* apoObserver)
{
moObserverList.push_front(apoObserver);
}
void CSubject::Dettach(CObserver* apoObserver)
{
moObserverList.remove(apoObserver);
}
void CSubject::Notify()
{
std::list<CObserver*>::iterator loIter = moObserverList.begin();
for (; loIter != moObserverList.end(); ++loIter)
{
(*loIter)->Update(this);
}
}
void CConcreteSubjectA::SetState(std::string aoState)
{
moState = aoState;
}
std::string CConcreteSubjectA::GetState()
{
return moState;
}