您的位置:首页 > 编程语言 > C语言/C++

C++源码分享(五):观察者模式泛型实现

2010-08-03 11:29 686 查看
提供观察者设计模式的泛型实现,特别是,当对象超出生命期时自动注销观察者

//<File>**********************************************************************

// Copyright (c) 2005

// 胡乐秋.

// 文件: ObserverEx.hpp

// 内容: 观察者模式的泛型实现

// 使用: 被观察者:

// 按以下形式声明类并在每一个更改状态的命令之后调用ObserverNotify(EventID,Parameters)

// class CMyClass : public HLQ_LIB::CObserverableT<CMyClass>

// {

// void ChangeState()

// {

// ...

// parameter_container_type Parameters;

// Parameters.push_back(OldState);

// Parameters.push_back(NewState);

// ObserverNotify(TEXT("ChangeState"),Parameters);

// }

// };

// 观察者:

// 按以下形式声明类,并实现OnObserveredEvent函数

// class UIMyClass : public HLQ_LIB::CMyClass::observer_type

// {

// virtual void OnObserveredEvent(const HLQ_LIB::CMyClass::observered_type* pMyClass,const CMyClass::event_id_type& EventID,const CMyClass::parameter_container_type& Parameters) const

// {

// state_type OldState=boost::any_cast<state_type>(Parameters[0]);

// state_type NewState=boost::any_cast<state_type>(Parameters[1]);

// MessageBox(0,EventID.c_str(),TEXT("OnObserveredEvent"),MB_OK);

// }

// };

// 初始化: 客户代码中应调用CMyClass或UIMyClass的Attach方法建立起被观察者和观察者对象之间的绑定关系

// 注意: 在观察者或被观察者对象超出其寿命范围时,组件可自动取消两者之间的绑定关系.

// 历史:

// 序号 修改时间 修改人 修改内容

// 1 2005/05/06 hlq 首次生成

//*********************************************************************</File>

//声明本头文件宏

#ifndef _OBSERVEREX_H

#define _OBSERVEREX_H

//包含头文件

#ifdef _MSC_VER

#if _MSC_VER < 1300

#pragma warning(disable:4786)

#endif //_MSC_VER < 1300

#endif //_MSC_VER

#include <vector>

#include <cassert>

#include <boost/any.hpp>

//开始名字空间

namespace HLQ_LIB

{

//<class>**********************************************************************

// 类名: CObserverT

// 目的: 观察者接口

//*********************************************************************</class>

template<class ObserveredType>

class CObserverT

{

////类型声明

public:

typedef typename ObserveredType::observer_type observer_type; //观察者类型

typedef typename ObserveredType::observered_type observered_type; //被观察者实际类型

typedef typename ObserveredType::event_id_type event_id_type; //被观察者事件ID类型,如字符串("删除对象")或int。缺省为字符串。

typedef typename ObserveredType::parameter_container_type parameter_container_type; //参数容器类型,常为std::vector或std::list等。缺省为std::vector。

typedef typename parameter_container_type::value_type parameter_type; //参数类型,常为变体如CComVariant、boost::any等。缺省为boost::any。

typedef std::vector<const observered_type*> observered_container_type;

typedef typename observered_container_type::value_type observered_value_type;

typedef typename observered_container_type::iterator observered_iterator;

typedef typename observered_container_type::const_iterator observered_const_iterator;

typedef typename observered_container_type::size_type observered_size_type;

typedef typename observered_container_type::size_type observered_index_type;

////基本查询

public:

//得到被观察者数量

observered_size_type GetObserveredCount() const {return m_Observereds.size();}

//检查是否已经绑定指定被观察者

bool HasAttach(const observered_type* pObservered) const;

//得到被观察者

observered_value_type GetObservered(observered_index_type Index) const{assert(Index<GetObserveredCount());return m_Observereds[Index];}

////命令

public:

//绑定被观察者(建立双向榜定)

void Attach(const observered_type* pObservered);

//取消被观察者绑定(取消双向榜定)

void Detach(const observered_type* pObservered);

//取消所有被观察者绑定(取消所有双向榜定)

void DetachAllObservereds();

////接口函数

protected:

//被观察者事件通知消息

friend observered_type;

virtual void OnObserveredEvent(const observered_type* pObservered,const event_id_type& EventID,const parameter_container_type& Parameters) const= 0;

////构造、析构函数

public:

//缺省构造函数

CObserverT(){};

//拷贝构造函数

CObserverT(const CObserverT& rhs);

//虚拟析构函数

virtual ~CObserverT();

//赋值操作俯重载

CObserverT& operator=(const CObserverT& rhs);

////数据成员

private:

observered_container_type m_Observereds;

};

//检查是否已经绑定指定观察者

template <class ObserveredType>

inline bool CObserverT<ObserveredType>::HasAttach(const observered_type* pObservered) const

{

//循环遍历每个观察者,检查是否已经注册

for(observered_const_iterator p=m_Observereds.begin();p!=m_Observereds.end();++p)

{

if(*p==pObservered)

return true;

}

return false;

}

//绑定被观察者(建立双向榜定)

template <class ObserveredType>

inline void CObserverT<ObserveredType>::Attach(const observered_type* pObservered)

{

assert(!HasAttach(pObservered));

m_Observereds.push_back(pObservered);

if(!pObservered->HasAttach(this))

(const_cast<observered_type*>(pObservered))->Attach(this);

assert(pObservered->HasAttach(this));

assert(HasAttach(pObservered));

}

//取消被观察者绑定(取消双向榜定)

template <class ObserveredType>

inline void CObserverT<ObserveredType>::Detach(const observered_type* pObservered)

{

assert(HasAttach(pObservered));

for(observered_iterator p=m_Observereds.begin();p!=m_Observereds.end();++p)

{

if(*p==pObservered)

{

m_Observereds.erase(p);

if(pObservered->HasAttach(this))

(const_cast<observered_type*>(pObservered))->Detach(this);

break;

}

}

assert(!pObservered->HasAttach(this));

assert(!HasAttach(pObservered));

}

//取消所有被观察者绑定(取消所有双向榜定)

template <class ObserveredType>

inline void CObserverT<ObserveredType>::DetachAllObservereds()

{

//循环释放每一个被观察者

while(GetObserveredCount()>0)

Detach(m_Observereds[0]);

}

//拷贝构造函数

template <class ObserveredType>

inline CObserverT<ObserveredType>::CObserverT(const CObserverT& rhs)

{

for(observered_const_iterator p=rhs.m_Observereds.begin();p!=rhs.m_Observereds.end();++p)

Attach(*p);

}

//虚拟析构函数(取消所有双向榜定)

template <class ObserveredType>

inline CObserverT<ObserveredType>::~CObserverT()

{

//清空所有被观察者

DetachAllObservereds();

}

//赋值操作俯重载

template <class ObserveredType>

CObserverT<ObserveredType>& CObserverT<ObserveredType>::operator=(const CObserverT& rhs)

{

if(&rhs!=this)

{

//清空所有被观察者

DetachAllObservereds();

for(observered_const_iterator p=rhs.m_Observereds.begin();p!=rhs.m_Observereds.end();++p)

Attach(*p);

}

return *this;

}

//<class>**********************************************************************

// 类名: CObserverableT

// 目的: 可被观察者

// 参数: ObserveredType - 被观察者具体类型,即本类的派生类

// EventIDType - 被观察者事件ID类型,如字符串("删除对象")或int。缺省为字符串。

// ParameterType - 参数类型,常为变体如CComVariant、boost::any等。缺省为boost::any。

// ParameterContainerType - 参数容器类型,常为std::vector或std::list等。缺省为std::vector。

//*********************************************************************</class>

template <class ObserveredType,class EventIDType=std::basic_string<TCHAR>,class ParameterType=boost::any,class ParameterContainerType=std::vector<ParameterType> >

class CObserverableT

{

////类型声明

public:

typedef CObserverableT<ObserveredType> observered_type;

typedef EventIDType event_id_type;

typedef ParameterType parameter_type;

typedef ParameterContainerType parameter_container_type;

typedef CObserverT<observered_type> observer_type;

typedef std::vector<const observer_type*> observer_container_type;

typedef typename observer_container_type::value_type observer_value_type;

typedef typename observer_container_type::iterator observer_iterator;

typedef typename observer_container_type::const_iterator observer_const_iterator;

typedef typename observer_container_type::size_type observer_size_type;

typedef typename observer_container_type::size_type observer_index_type;

////基本查询

public:

//得到观察者数量

observer_size_type GetObserverCount() const {return m_Observers.size();}

//检查是否已经绑定指定观察者

bool HasAttach(const observer_type* pObserver) const;

//得到观察者

observer_value_type GetObserver(observer_index_type Index) const{assert(Index<GetObserverCount());return m_Observers[Index];}

////命令

public:

//绑定观察者(建立双向榜定)

void Attach(const observer_type* pObserver);

//取消观察者绑定(取消双向榜定)

void Detach(const observer_type* pObserver);

//取消所有被观察者绑定(取消所有双向榜定)

void DetachAllObservers();

////派生类调用函数

protected:

//通知所有观察者

void ObserverNotify(const event_id_type& EventID,const parameter_container_type& Parameters=parameter_container_type()) const;

////构造、析构函数

public:

//缺省构造函数

CObserverableT(){};

//拷贝构造函数

CObserverableT(const CObserverableT& rhs);

//虚拟析构函数

virtual ~CObserverableT(void);

//赋值操作俯重载

CObserverableT& operator=(const CObserverableT& rhs);

////数据成员

private:

observer_container_type m_Observers;

};

//检查是否已经绑定指定观察者

template <class ObserveredType,class EventIDType,class ParameterType,class ParameterContainerType>

inline bool CObserverableT<ObserveredType,EventIDType,ParameterType,ParameterContainerType>::HasAttach(const observer_type* pObserver) const

{

//循环遍历每个观察者,检查是否已经注册

for(observer_const_iterator p=m_Observers.begin();p!=m_Observers.end();++p)

{

if(*p==pObserver)

return true;

}

return false;

}

//绑定观察者(建立双向榜定)

template <class ObserveredType,class EventIDType,class ParameterType,class ParameterContainerType>

inline void CObserverableT<ObserveredType,EventIDType,ParameterType,ParameterContainerType>::Attach(const observer_type* pObserver)

{

assert(!HasAttach(pObserver));

m_Observers.push_back(pObserver);

if(!pObserver->HasAttach(this))

(const_cast<observer_type*>(pObserver))->Attach(this);

assert(HasAttach(pObserver));

assert(pObserver->HasAttach(this));

}

//取消观察者绑定(取消双向榜定)

template <class ObserveredType,class EventIDType,class ParameterType,class ParameterContainerType>

inline void CObserverableT<ObserveredType,EventIDType,ParameterType,ParameterContainerType>::Detach(const observer_type* pObserver)

{

assert(HasAttach(pObserver));

for(observer_iterator p=m_Observers.begin();p!=m_Observers.end();++p)

{

if(*p==pObserver)

{

m_Observers.erase(p);

if(pObserver->HasAttach(this))

(const_cast<observer_type*>(pObserver))->Detach(this);

break;

}

}

assert(!HasAttach(pObserver));

assert(!pObserver->HasAttach(this));

}

//取消所有被观察者绑定(取消所有双向榜定)

template <class ObserveredType,class EventIDType,class ParameterType,class ParameterContainerType>

inline void CObserverableT<ObserveredType,EventIDType,ParameterType,ParameterContainerType>::DetachAllObservers()

{

//循环释放每一个观察者

while(GetObserverCount()>0)

Detach(m_Observers[0]);

}

//拷贝构造函数

template <class ObserveredType,class EventIDType,class ParameterType,class ParameterContainerType>

inline CObserverableT<ObserveredType,EventIDType,ParameterType,ParameterContainerType>::CObserverableT(const CObserverableT& rhs)

{

for(observer_const_iterator p=rhs.m_Observers.begin();p!=rhs.m_Observers.end();++p)

Attach(*p);

}

//虚拟析构函数

template <class ObserveredType,class EventIDType,class ParameterType,class ParameterContainerType>

inline CObserverableT<ObserveredType,EventIDType,ParameterType,ParameterContainerType>::~CObserverableT()

{

//清空所有观察者

DetachAllObservers();

}

//赋值操作俯重载

template <class ObserveredType,class EventIDType,class ParameterType,class ParameterContainerType>

CObserverableT<ObserveredType,EventIDType,ParameterType,ParameterContainerType>& CObserverableT<ObserveredType,EventIDType,ParameterType,ParameterContainerType>::operator=(const CObserverableT& rhs)

{

if(&rhs!=this)

{

//清空所有观察者

DetachAllObservers();

for(observer_const_iterator p=rhs.m_Observers.begin();p!=rhs.m_Observers.end();++p)

Attach(*p);

}

return *this;

}

//通知所有观察者

template <class ObserveredType,class EventIDType,class ParameterType,class ParameterContainerType>

inline void CObserverableT<ObserveredType,EventIDType,ParameterType,ParameterContainerType>::ObserverNotify(const event_id_type& EventID,const parameter_container_type& Parameters) const

{

for(observer_const_iterator p=m_Observers.begin();p!=m_Observers.end();++p)

{

(*p)->OnObserveredEvent(this,EventID,Parameters);

}

}

}//HLQ_LIB名字空间结束

#endif //假如未定义_OBSERVEREX_H宏

胡乐秋
2010/8/3 http://blog.csdn.net/hlqyq
内容来自用户分享和网络整理,不保证内容的准确性,如有侵权内容,可联系管理员处理 点击这里给我发消息
标签: