现在的位置: 首页 > 综合 > 正文

观察者模式使用心得

2013年08月18日 ⁄ 综合 ⁄ 共 1032字 ⁄ 字号 评论关闭

观察者模式作为GOF 24个常见设计模式之一,在实际编程中应用非常广泛,该设计模式的基本内容,可以参照http://blog.csdn.net/alicehyxx/archive/2009/07/31/4397114.aspx.

最近在使用观察者模式的过程中,遇到两个非常棘手的问题:

1、    对于目标的更新,导致观察者多次更新的问题。

2、    若目标为指针,观察者Attach()目标后,目标指针被删除,导致观察者与目标Detach()时,软件死机的问题。

一、              观察者多次更新

对于观察者多次更新的问题,可以选择手动调用目标的Notify()函数。但多数情况下,手动调用函数不能满足需求。我们可以给目标增加一个时间戳,当目标修改后,设置时间戳为更新时间点;而后利用OnIdle()函数,检查所有目标的时间戳,并通知观察者更新,大致代码如下:

static ULONGLONG ull = 0;

if(Notify(ull))

{

       ull = GetTimeStamp();

}

Notify()函数中,判断目标时间戳是否大于ull值,若大于,则通知观察者更新,更新后设置目标时间戳为ull;若小于,则直接返回。更新后,保存时间戳,防止目标未更新,再次通知观察者更新。

二、              目标指针被删除

对于目标指针被删除的问题,可以采用引用计数的方法解决。目标指针不能直接delete,而通过引用计数技术删除。

目标重载Wsubject()Attach()函数和Detach()函数,大致代码如下:

class Qsubject : public Wsubject

{

Public:

       void ref()

{

       ++ m_iref;

}

       void unref()

{

n     m_iref;

n     if(m_iref == 0)

delete this;

}

      

       virtual void Attach(Wobserver* pObserver)

{

              Wsubject::Attach(pObserver);

              ref();

}

       virtual void Detach(Wobserver* pObserver)

{

              Wsubject:: Detach (pObserver);

              unref();

}

private:

       int m_iref;

}

 

抱歉!评论已关闭.