观察者模式

来源:互联网 发布:js经典面试题 编辑:程序博客网 时间:2024/05/08 07:42

    观察者模式的意图是:定义对象间的一种关系,当一个对象的状态发生变化时,所有依赖于它的对象都能得到通知。

    你可以考虑这样一种应用,当一个论坛注册了个新用户后,论坛程序自动发一个站内欢迎消息和email。以后可能还有需求说同时也用手机发一条短信等等。在这里面,新用户是一个对象,发站内欢迎消息是一个对象,发email也是一个对象,还有发手机短信也可以是个对象。当新用户注册时(状态改变),其它依赖于它的对象都得到通知(发欢迎消息、email、手机短信等对象得到通知并执行相应动作)。

    观察者模式可以用来实现这种应用,并且可以适应不断变化的需求。如有新的对象需要被通知,只需增加新的观察者而不必改动原来的代码。下面看下具体的代码:

 
//----------------------------future.h开始----------------------------------
#ifndef FUTURE_H
#define FUTURE_H

#include 
<list>
using namespace std;

#include 
"mutex.h"

template
<typename T>
class CFuture;

template
<typename T>
class CObserver;

template
<typename T>
class CFuture
{
private:
//声明operator=和拷贝构造为private,以阻止CFuture对象之间的赋值
void operator = ( const CFuture<T> &r )
{
}

CFuture(
const CFuture<T> &r )
{
}

public:
CFuture() : m_pValue(NULL)
{
}


virtual ~CFuture()
{
   delete m_pValue;
}


int Attach( CObserver<T> *pObserver )
{//增加一个观察者
   if( NULL == pObserver )
   
{
    
return -1;
   }


   AUTO_GUARD( g, ThreadMutex, m_lock );

   m_ObserverPtrList.push_back( pObserver );

   
ifthis->m_pValue )
   
{
    pObserver
->Update( *this );
   }


   
return 0;
}


int Detach( CObserver<T> *pObserver )
{//解除一个观察者
   AUTO_GUARD( g, ThreadMutex, m_lock );

   m_ObserverPtrList.remove( pObserver );

   
return 0;
}


int Set( const T & r )
{//设置值
   if( NULL == this->m_pValue )
   
{
    AUTO_GUARD( g, ThreadMutex, m_lock );

    
if( NULL == this->m_pValue )
    
{
     
this->m_pValue = new T(r);
    }


    
ifthis->m_pValue )
    
{//通知列表中的所有观察者
     list<OBSERVER_T *>::iterator it = m_ObserverPtrList.begin();
     
for( ; it != m_ObserverPtrList.end(); it++ )
     
{
      OBSERVER_T 
*pObserver = *it;
      pObserver
->Update( *this );     
     }


     
return 0;
    }
   
   }


   
return -1;
}


int Get( T & r ) const
{//获取值
   if!this->IsReady() )
   
{
    
return -1;
   }

   r 
= *m_pValue;
   
return 0;
}


bool IsReady() const
{//判断值是否已设置
   return ( m_pValue != NULL );
}


private:
typedef CObserver
<T> OBSERVER_T;

private:
* m_pValue;        //对象内部的值
ThreadMutex m_lock; //访问对象内部资源的锁
list<OBSERVER_T *> m_ObserverPtrList; //观察者列表
}
;

template
<typename T>
class CObserver
{//观察者接口
public:
CObserver()
{
}

virtual ~CObserver()
{
}

//观察者被通知的接口
virtual void Update( const CFuture<T> &fu ) = 0;
}
;

#endif
//----------------------------future.h开始----------------------------------

//----------------------------主程序文件observer.cpp开始----------------------------------
#include "future.h"

#include 
<iostream>
#include 
<string>
using namespace std;

class CMyObserverA : public CObserver<string>
{//观察者A
public:
CMyObserverA()
{
}

virtual ~CMyObserverA()
{
}


virtual void Update( const CFuture<string> &fu )
{//观察者A被通知
   string value;
   fu.Get( value );
   cout 
<< "call CMyObserverA when future set to: " << value << endl;
}

}
;

class CMyObserverB : public CObserver<string>
{//观察者B
public:
CMyObserverB()
{
}

virtual ~CMyObserverB()
{
}


virtual void Update( const CFuture<string> &fu )
{//观察者B被通知
   string value;
   fu.Get( value );
   cout 
<< "call CMyObserverB when future set to: " << value << endl;
}

}
;

int _tmain(int argc, _TCHAR* argv[])
{
CFuture
<string> myfu;
CMyObserverA myoba;
CMyObserverB myobb;

myfu.Attach( 
&myoba );
myfu.Attach( 
&myobb );

myfu.Set( 
"123456" );


return 0;
}

//----------------------------主程序文件observer.cpp结束----------------------------------
    如代码所示,CFuture是个状态会被改变的类,CObserver是所有观察者的公共接口,可以将多个CObserver观察者attach到 CFuture对象,这样当CFuture对象状态改变时(Set被调用),attach到该对象的观察者就会得到通知(Update被调用)。代码很简单,就不多做解释了,future.h中用到的mutex.h在另一篇文章“定界加锁模式”中有。
原创粉丝点击