设计模式学习笔记(二十一)——Observer观察者

本文介绍了一种常用的设计模式——观察者模式,通过示例详细解释了如何实现对象间的依赖关系,使得当一个对象状态发生变化时,所有依赖该对象的对象都能得到通知并自动更新。

十九、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和两个观察者
AnalogClockDigitalClock
*/
ClockTimer* timer = new ClockTimer;
AnalogClock* analogClock = new AnalogClock(timer);
DigitalClock* digitalClock = new DigitalClock(timer);
/*
*/

 

个人理解:

观察者模式中有两个重要的类层次:一是观察者类;二是目标对象类。观察者类定义了一个模板方法Update,并在子类中重定义,其作用是根据传入的参数来确定是否是希望的目标对象发出的更新来执行动作(本例中是Draw动作),注意:观察者子类中应该有个指针指向目标对象。而目标对象类则应该有方法记录多个观察者(本例中使用List,并有AttachDetach操作),并且有个操作能够向观察者们发出更新(本例中的Notify操作),注意:Notify应该在完成所有事情以后调用(即放在代码的最后,本例的Tick中)。

 
评论
成就一亿技术人!
拼手气红包6.0元
还能输入1000个字符
 
红包 添加红包
表情包 插入表情
 条评论被折叠 查看
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值