Observer模式的理解

      最近的项目中遇到了多个对象之间协作的设计问题,经过参考别的一些代码,发现解决这种一对多的对象间协作问题,通常使用Observer模式进行设计。什么是Observer(观察者)模式呢?下面举一个简单的例子。

    假设我们要设计一个交通状况监控系统,收到的数据封装成TrafficData类,然后把他拥堵状况用图形显示出来,处理该显示用TrafficMap类实现,然后又想以表格形式显示出来,那么用TrafficTable类实现。当TrafficData变更的时候,需要通知TrafficMap和TrafficTable更新他们的显示,一种直观的做法如下:

    在TrafficData中分别添加TrafficTable和TrafficMap两个实例m_pTMap, m_pTTable作为成员。定义一个UpdateDisplay()函数,代码类似于:

     TrafficData::UpdateDisplay()

      {

          m_pTMap->UpdateData(m_data);

          m_pTTable->UpdateData(m_data);

     }

    现在,假如我们又想把交通状况朗读出来(用TrafficVoice类实现),则要在TrafficData中增加TrafficVoice成员, 并在UpdateDisplay()中添加代码。每次的需求变更导致了TrafficData的更改,不利于代码重用和扩展。我们怎么利用C++的抽象机制更好解决这个问题呢?这是就用到Observer模式。

     我们平时订阅网上新闻时,服务端便把我加到他的用户列表中,我们就成为一个Observer。当有新的新闻,服务端会遍历用户列表,通知每一个Observer更新,这就是Observer模式的思想。现在,我们用Observer改进我们的设计。定义一个抽象基类叫 Subject, 定义一个纯虚函数UpdateDisplay()和一个Observer列表。 TrafficData从Subject继承,并实现UpdateDisplay()函数,代码如下:

  class Subject {

        vector<Observer*>  m_observerlist;   //Observer列表

        virtual void UpdateDisplay() = 0;

        void AddObserver( Observer* newMember); //添加观察者到列表

        void RemoveObserver( Observer* member); //删除一个观察者

  }

  class TrafficData : public Subject {

        virtual void UpdateDisplay() {

             逐一通知m_observerlist中的每个成员,调用他们的UpdateData:

             m_observerlist[i]->UpdateData( CData  data);

        }

  }

      在Observer抽象基类中定义UpdateData纯虚函数和Subject成员,然后TrafficMap, TrafficTable继承Subject, 代码如下:

 class Observer {

        Subject*  m_pSubject;

        virtual void UpdateData() = 0;

   }

 class TrafficMap : public Observer

 {

     virtual void UpdateData( CData data)  {

           data是最新数据,更新显示;

     }

 }

     如果加入新的功能,如TrafficVoice把数据朗读出来,则只需要从Observer基类中继承,然后改写UpdateData就可以了,通过Subject类的AddObserver加入到列表中,每当数据有更新,则TrafficVoice类会被通知。

     Observer类有效地降低了多个协作对象的耦合度(loose couple, 松耦合),有利于代码重用。特别是在大型,需求多变的工程中显得很有必要。实际上,MFC中的Document/View/Frame框架就是Observer模式的一个非常好的例子,他把数据和显示分离,由数据驱动视图的更新,详情可参考侯俊杰的<深入浅出MFC>。 

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值