当一个对象改变时需要同时通知其他多个对象,或者说一个对象依赖另一个对象的时候,使用观察者模式可以将这两者封装在独立的对象中使他们各自独立地改变和复用。
观察者模式所做的工作就是在接触耦合,让相互耦合的双方都依赖于抽象而不是具体类,从而使得各自的改变都不会影响到对方。(引用自 《大话设计模式》)
下面提供一个观察者模式的C++实现版本:
#pragma once
#include <assert.h>
#include <iostream>
#include <list>
#include <string>
using std::list;
using std::cout;
using std::endl;
using std::string;
//观察者需要通知者当前的状态信息,因此需要保存INotify指针
class INotify; //提前声明
class IObserver
{
public:
IObserver(const char* pName, INotify* pNotify)
: m_strName(pName)
, m_pNotify(pNotify)
{
}
virtual void Update() = 0;
protected:
string m_strName;
INotify* m_pNotify;
};
class INotify
{
public:
virtual ~INotify()
{
list<IObserver*>::iterator itor = m_pObserverList.begin();
IObserver* pObs = NULL;
while( itor != m_pObserverList.end() )
{
pObs = *itor;
delete pObs;
itor++;
}
m_pObserverList.clear();
}
virtual void Add(IObserver* pObs)
{
assert(pObs);
m_pObserverList.push_back(pObs);
}
virtual bool Remove(IObserver* pObs)
{
assert(pObs);
list<IObserver*>::iterator itor = m_pObserverList.begin();
while( itor != m_pObserverList.end() )
{
IObserver* pFind = *itor;
if ( pFind == pObs )
return true;
itor++;
}
return false;
}
virtual void Notify()
{
list<IObserver*>::iterator itor = m_pObserverList.begin();
while( itor != m_pObserverList.end() )
{
IObserver* pObs = *itor;
pObs->Update();
itor++;
}
}
const string& GetStatus()const { return m_strStatus; }
void SetStatus(const string& strStatus) { m_strStatus = strStatus; }
private:
list<IObserver*> m_pObserverList;
string m_strStatus;
};
//试图通知类,通知所有视图更新状态
class CViewNotify
: public INotify
{
public:
//做一些独立的工作
};
class CFrameNotify
: public INotify
{
public:
//做一些独立的工作
};
class CScrollView
: public IObserver
{
public:
CScrollView(const char* pName, INotify* pNotify)
:IObserver(pName, pNotify)
{
}
virtual void Update()
{
cout<<m_strName<<" need update now , the status is "<<m_pNotify->GetStatus()<<endl;
}
};
class CEditView
: public IObserver
{
public:
CEditView(const char* pName, INotify* pNotify)
:IObserver(pName, pNotify)
{
}
virtual void Update()
{
cout<<m_strName<<" need update now , the status is "<<m_pNotify->GetStatus()<<endl;
}
};
阅读《大话设计模式》后写的,算是小练习吧。