一 意图
它定义了一种一对多的依赖关系,当目标的状态发生改变时,所有的观察者都会得到通知而自动更新,不用实时的监控目标。
二 别名
observer,依赖(depends),发布-订阅(Publish-Subsciribe)
三 适用性
1 当一个抽象模型有两个方面,其中一个方面依赖于另一个方面。将这二者封装在独立的对象中,以使得它们可以各自相互独立的改变和复用。
2 当对一个对象的改变需要同时改变其他对象,而不知道具体有多少对象需要被改变时。
3 当一个对象必须通知其它对象,而它又不能假定其它对象是谁。换言之,你不希望这些对象是紧密耦合的。
四 结构
五 实现
.h
#ifndef __CLASS__H
#define __CLASS__H
#include <string>
#include <list>
using std::list;
using std::string;
class CSubject;
class CObserver
{
public:
virtual void Update(CSubject* subject)=0;
virtual ~CObserver(){};
};
class CSubject
{
public:
void Attach(CObserver* observer);
void Detach(CObserver* observer);
void Modify();
virtual ~CSubject(){};
virtual string GetState()=0;
virtual void SetState(const string& state)=0;
private:
list<CObserver* > m_observerList;
};
class CConcreteSubject:public CSubject
{
public:
string GetState();
void SetState(const string& state);
private:
string m_state;
};
class CConcreteObserverA:public CObserver
{
public:
void Update(CSubject* subject);
};
class CConcreteObserverB:public CObserver
{;
public:
void Update(CSubject* subject);
};
class CConcreteObserverC:public CObserver
{
public:
void Update(CSubject* subject);
};
#endif
.cpp
#include "class.h"
#include <iostream>
using namespace std;
void CSubject::Attach(CObserver* observer)
{
m_observerList.push_back(observer);
}
void CSubject::Detach(CObserver* observer)
{
if(! m_observerList.empty() )
{
m_observerList.remove(observer);
}
}
void CSubject::Modify()
{
list<CObserver *>::iterator ite=m_observerList.begin();
for(;ite!=m_observerList.end();ite++)
{
(*ite)->Update(this);
}
}
string CConcreteSubject::GetState()
{
return m_state;
}
void CConcreteSubject::SetState(const string& state)
{
m_state=state;
}
void CConcreteObserverA::Update(CSubject* subject)
{
string state=subject->GetState();
if(state == "yes")
{
cout<<"CConcreteObserverA is ready!\n";
}
}
void CConcreteObserverB::Update(CSubject* subject)
{
string state=subject->GetState();
if(state == "yes")
{
cout<<"CConcreteObserverB is ready!\n";
}
}
void CConcreteObserverC::Update(CSubject* subject)
{
string state=subject->GetState();
if(state == "yes")
{
cout<<"CConcreteObserverC is ready!\n";
}
}
client:
#include "class.h"
void main()
{
CSubject* pSubject=new CConcreteSubject();
CObserver* pA= new CConcreteObserverA();
CObserver* pB=new CConcreteObserverB();
CObserver* pC=new CConcreteObserverC();
pSubject->Attach(pA);
pSubject->Attach(pB);
pSubject->Attach(pC);
pSubject->Detach(pB);
pSubject->SetState("yes");
pSubject->Modify();
delete pSubject;
delete pA;
delete pB;
delete pC;
}