提供观察者设计模式的泛型实现,特别是,当对象超出生命期时自动注销观察者
//<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