十九、Observer(观察者)
情景举例:
定义对象间的一种一对多的依赖关系,当一个对象的状态发生改变时, 所有依赖于它的对象都得到通知并被自动更新。
代码示例:
/* 观察者的抽象父类。注意:Update是一个模板方法
*/
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:
List<Observer*> *_observers;
};
/*
*/
void Subject::Attach (Observer* o) {
_observers->Append(o);
}
/*
*/
void Subject::Detach (Observer* o) {
_observers->Remove(o);
}
/* Notify就是依次更新列表中的观察者,使用了迭代器。注意,将this作为
Update的参数
*/
void Subject::Notify () {
ListIterator<Observer*> i(_observers);
for (i.First(); !i.IsDone(); i.Next()) {
i.CurrentItem()->Update(this);
}
}
/* ClockTimer是一个具体的目标对象。在Tick的时候通知更新
*/
class ClockTimer : public Subject {
public:
ClockTimer();
/*
*/
virtual int GetHour();
virtual int GetMinute();
virtual int GetSecond();
/*
*/
void Tick();
};
/*
*/
void ClockTimer::Tick () {
// update internal time-keeping state
// ...
Notify();
}
/* DigitalClock是一个具体的观察者。注意:在私有成员中有一个预定义好的
ClockTimer*类型的观察者指针。
*/
class DigitalClock: public Widget, public Observer {
public:
DigitalClock(ClockTimer*);
virtual ~DigitalClock();
/* Observer子类必须重定义Update操作
*/
virtual void Update(Subject*);
// overrides Observer operation
/*
*/
virtual void Draw();
// overrides Widget operation;
// defines how to draw the digital clock
private:
ClockTimer* _subject;
};
/*
*/
DigitalClock::DigitalClock (ClockTimer* s) {
_subject = s;
_subject->Attach(this);
}
DigitalClock::~DigitalClock () {
_subject->Detach(this);
}
/* 当目标对象确实是希望接收的类型时,才作出相应的动作。
*/
void DigitalClock::Update (Subject* theChangedSubject) {
if (theChangedSubject == _subject) {
Draw();
}
}
/*
*/
void DigitalClock::Draw () {
// get the new values from the subject
int hour = _subject->GetHour();
int minute = _subject->GetMinute();
// etc.
// draw the digital clock
}
/* 另一个观察者的具体类。
*/
class AnalogClock : public Widget, public Observer {
public:
AnalogClock(ClockTimer*);
virtual void Update(Subject*);
virtual void Draw();
// ...
};
/* 主程序很可能这样写来定义一个目标对象ClockTimer和两个观察者
AnalogClock与DigitalClock。
*/
ClockTimer* timer = new ClockTimer;
AnalogClock* analogClock = new AnalogClock(timer);
DigitalClock* digitalClock = new DigitalClock(timer);
/*
*/
个人理解:
观察者模式中有两个重要的类层次:一是观察者类;二是目标对象类。观察者类定义了一个模板方法Update,并在子类中重定义,其作用是根据传入的参数来确定是否是希望的目标对象发出的更新来执行动作(本例中是Draw动作),注意:观察者子类中应该有个指针指向目标对象。而目标对象类则应该有方法记录多个观察者(本例中使用List,并有Attach和Detach操作),并且有个操作能够向观察者们发出更新(本例中的Notify操作),注意:Notify应该在完成所有事情以后调用(即放在代码的最后,本例的Tick中)。
本文介绍了一种常用的设计模式——观察者模式,通过示例详细解释了如何实现对象间的依赖关系,使得当一个对象状态发生变化时,所有依赖该对象的对象都能得到通知并自动更新。
1820

被折叠的 条评论
为什么被折叠?



