设计模式(六)----观察者模式

1.引子

    今天逛论坛,看到一个很实用的帖子,问的是子对象如何通知父对象?
  代码是:
   
class A
{
   bool flag;
   void set_status()
   {
       flag = true;
    }
};
class B
{
   B()
   {
       A a;
       a.flag = false;
    }
   bool get_a_status()
   {
       return a.flag;
    }
};
int main()
{
   B b;
   while(1)
   {
       if(b.get_a_status())
       {
           printf("Yes, a is true\n");
           break;
        }
   }
}
这里有个明显的问题就是父对象b要轮询子对象a的状态是不是true,但是最好的办法就是
子对象的状态变化了,自动通知父对象。这个要怎么做才好呢。使用事件?

下面有人建议用观察者模式。
这就引出了我初步学习观察者模式,并写下这篇很水的博客。

2.概念级学习

UML图。


根据这张图,我们写一下,论坛上的代码。

//Observer.h
#ifndef _Observer_
#define _Observer_
class Observer
{
public:
    Observer(){}
    virtual ~Observer(){}
    virtual void Update(){}
};
#endif

//Object.h
#ifndef _Object_
#define _Object_
#include "Observer.h"
#include <list>
using namespace std;
class Object
{
    public:
        Object(){}
        virtual ~Object(){}
        void Attach(Observer * observer){m_obsservers.push_back(observer);}
        void Remove(Observer * observer){m_obsservers.push_back(observer);}
        void Notify()
        {
            std::list<Observer *>::iterator iter =m_obsservers.begin();
            for(;iter != m_obsservers.end();iter++)
                (*iter)->Update();
        }
        virtual void set_status(){}
        virtual bool get_status(){}
    private:
        list<Observer *> m_obsservers;
};
#endif

//A.h
#ifndef _A_
#define _A_
#include "Object.h"

class A : public Object
{
    public:
        A(){}
        virtual ~A(){}
    bool flag;
    void set_status();
    bool get_status();
};
#endif


//B.h
#ifndef _B_
#define _B_
#include "A.h"
#include "Observer.h"
#include "Object.h"
#include <unistd.h>
#include <iostream>
class B:public Observer
{
    private:
        Object * m_object;
    public:
    B(Object * object):m_object(object)
    {
        /*m_object.set_status();*/
    }
    void Update();
    bool get_a_status();
};
#endif

#include <iostream>
#include "A.h"
#include "B.h"
#include "Observer.h"
#include "Object.h"
using namespace std;

int main()
{
   Object * object = new A();   
   Observer * observer1 = new B(object);
   object->Attach(observer1);
   object->set_status();
   object->Notify();
   object->set_status();
   object->Notify();
   delete object;
   delete observer1;
   //while(1)
   //{
   //if(b.get_a_status())
   //{
   //cout << "Yes, a is true"<<endl;
   //}
   //else
   //cout << "NO, a is false" << endl;
   //sleep(1);
   //}
}

核心代码如上。实现了 A改变状态,通知B执行update函数的功能。
A继承于Object,Object里面实现了一个list <observer *> 来调用B。
A调用set_status()改变状态后,再调用Notify()通知给所有list<observer *>里的观察者,调用观察者的update。每一个观察者实体都是继承来自B的 ,所以实现了调用B实体的目的。


这样理解起来避免了 while循环查看,和sigal很像;

信号和槽好像就是封装了 观察者模式。

被调用者(被通知执行动作者)继承public has_slots<>  ;

通知者 包含了signal0<> ToSniffer; 

  1. myLoc.ToSniffer.connect(&mysniffer,&Sniffer::startSniffer);  
  2.             myTopo.ToSniffer.connect(&mysniffer,&Sniffer::startSniffer);  
再通过 这里 使包含的ToSniffer 与被调用者mysniffer链接,调用方法startSniffer。

信号和槽的概念也是为了解决 父对象通知子对象来执行某函数的功能。


由此可见我们还是不要自己封装 observer类了,有现成的Sigslot使用。

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值