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

    提供观察者设计模式的泛型实现,特别是,当对象超出生命期时自动注销观察者

 

//<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

你可能感兴趣的:(C++源码分享(五):观察者模式泛型实现)