1、意图
定义对象间的一种一对多的依赖关系,当一个对象的状态发生改变时,所有依赖于它的对象都得到通知并被自动更新。
2、动机
将一个系统分割成一系列相互协作的类有一个常见的副作用:需要维护相关对象间的一致性。我们不希望为了维持一致性而使各类紧密耦合,因为这样降低了它们的可重用性。
3、适用性
在以下任一情况下可以使用观察者模式:
1)当一个抽象模型有两个方面,其中一个方面依赖于另一方面。将这二者封装在独立的对象中以使它们可以各自独立地改变和复用。
2)当对一个对象的改变需要同时改变其它对象,而不知道具体有多少对象有待改变。
3)当一个对象必须通知其它对象,而它不能假定其它对象是谁。换言之,你不希望这些对象是紧密耦合的。
4、C++实例
// Test.cpp : 定义控制台应用程序的入口点。
//
#include "stdafx.h"
#include <iostream>
#include <Windows.h>
#include <list>
#include <string>
using namespace std;
class Subject;
class Observer
{
public:
virtual ~Observer()
{
}
virtual void Update( Subject * theChangedSubject ) = 0;
protected:
Observer()
{
}
};
class Subject
{
public:
virtual ~Subject()
{
delete _observer;
}
virtual void Attach( Observer *O );
virtual void Detach( Observer *O );
virtual void Notify();
protected:
Subject()
{
_observer = new list<Observer*>;
_subject = this;
}
private:
list<Observer*> *_observer;
static Subject *_subject;
};
Subject * Subject::_subject = NULL;
void Subject::Attach( Observer *O )
{
_observer->push_back( O );
}
void Subject::Detach( Observer *O )
{
list<Observer*>::iterator it = _observer->begin();
for ( ; it != _observer->end(); it++ )
{
if ( (*it) == O )
{
_observer->erase( it );
}
}
}
void Subject::Notify()
{
list<Observer*>::iterator it = _subject->_observer->begin();
for ( ; it != _subject->_observer->end(); it++ )
{
Observer *Ob = ( *it );
Ob->Update( NULL );
}
}
class ClockTimer: public Subject
{
public:
ClockTimer()
{
}
void Tick()
{
Notify();
}
};
class DigitalClock:public Observer
{
public:
DigitalClock( ClockTimer *a )
{
_subject = a;
_subject->Attach( this );
}
virtual ~DigitalClock()
{
_subject->Detach(this);
}
virtual void Update( Subject *theChangedSubject )
{
cout<<"DigitalClock:Update"<<endl;
}
private:
ClockTimer *_subject;
};
class AnalogClock:public Observer
{
public:
AnalogClock( ClockTimer *a )
{
_subject = a;
_subject->Attach( this );
}
virtual ~AnalogClock()
{
_subject->Detach(this);
}
virtual void Update( Subject *theChangedSubject )
{
cout<<"AnalogClock:Update"<<endl;
}
private:
ClockTimer *_subject;
};
int _tmain(int argc, _TCHAR* argv[])
{
ClockTimer *timer = new ClockTimer;
DigitalClock *digitalclock = new DigitalClock(timer);
AnalogClock *analogclock = new AnalogClock(timer);
int times = 10;
while ( times-- > 0 )
{
timer->Tick();
Sleep( 10000 * 2 );
}
return 0;
}