观察者模式
来源:互联网 发布: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 );
if( this->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);
}
if( this->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:
T * 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结束----------------------------------
#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 );
if( this->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);
}
if( this->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:
T * 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结束----------------------------------
- 观察者模式
- 观察者模式
- 观察者模式
- 观察者模式
- 观察者模式
- 观察者模式
- 观察者模式
- 观察者模式
- 观察者模式
- 观察者模式
- 观察者模式
- 观察者模式
- 观察者模式
- 观察者模式
- 观察者模式
- 观察者模式
- 观察者模式
- 观察者模式
- myeclipse+struts+tomcat5.5 中文问题
- 定界加锁模式
- 访问不同程序集的方法
- “加班”的定义
- Oracle 9i & 10g编程艺术-深入数据库体系结构——配置环境
- 观察者模式
- jbpm
- 采用Click Once更新,中途更改升级地址的方法
- 新锐2007年上刀光剑影的100条激进言论(年度盘点)
- 访问修饰符
- 如何才能更加全面的看问题?你的沟通如何才能更有效?
- 积极向上,乐于助人
- 狙剑 V2008-0112版
- 囧《SimCIty》 源代码基于GPL发布。。。。