代码改变世界

C++设计模式之Observer(观察者)模式

2011-01-24 17:16  chainchan  阅读(606)  评论(0编辑  收藏  举报

作用:定义对象间的一种一对多的依赖关系,当一个对象的状态发生改变时,所有依赖于它的对象都得到通知并被自动更新。比如,QQ中你的好友上线下,他们的头像亮起,熄灭。

 

以下是参考代码

#include <Windows.h>
#include
<list>
using namespace std;

class Subject;

class Observer {
public:
virtual ~Observer();
virtual void Update(Subject* theChangedSubject) = 0;
protected:
Observer();
};

class Subject {
public:
virtual ~Subject();
virtual void Attach(Observer*);
virtual void Detach(Observer*);
virtual void Notify();
protected:
Subject();
private:
std::list
<Observer*> *_observers;
};

void Subject::Attach(Observer* obj)
{
_observers
->push_back(obj);
}

void Subject::Detach(Observer* obj)
{
typedef std::list
<Observer*>::iterator LI;
for (LI iter=_observers->begin();
iter
!=_observers->end();
++iter)
{
if (*iter == obj)
{
_observers
->erase(iter);
break;
}
}
}

void Subject::Notify()
{
typedef std::list
<Observer*>::iterator LI;
std::list
<Observer*> *i(_observers);
for (LI it=i->begin(); it!=i->end(); ++it)
{
(
*it)->Update(this);
}
}

//ClockTimer是一个用于存储和维护一天时间的具体目标。它每秒通知一次它的观察者。
class ClockTimer : public Subject {
public:
ClockTimer();
virtual int GetHour();
virtual int GetMinute();
virtual int GetSecond();

void Tick();
};

void ClockTimer::Tick()
{
Sleep(
1000);
Notify();
}


class Widget;
//DigitalClock类来显示时间。Widget类继承了它的图形功能
class DigitalClock : public Widget, public Observer {
public:
DigitalClock(ClockTimer
*);
virtual ~DigitalClock();

virtual void Update(Subject*); //overrides Observer operation

virtual void Draw(); //overrides Widget operation
private:
ClockTimer
* _subject;
};

DigitalClock::DigitalClock(ClockTimer
* time)
{
_subject
= time;
_subject
->Attach(this);
}

DigitalClock::
~DigitalClock()
{
_subject
->Detach(this);
}

void DigitalClock::Update(Subject* theChangeSubject)
{
if (theChangeSubject == _subject)
{
Draw();
}
}

void DigitalClock::Draw()
{
int hour = _subject->GetHour();
int minute = _subject->GetMinute();
int second = _subject->GetSecond();

//draw the digital clock;
}



int main()
{
ClockTimer
* timer = new ClockTimer;
DigitalClock
* digitalClock = new DigitalClock(timer);
}