C++源码分享(六):许可者模式泛型实现

    许可者模式是指对象在更改状态前发布事件,当其他对象同意时才更该对象属性。特别适用于父对象对子对象的管理,通过这种模式,父对象在允许用户直接访问子对象时附加特定的约束,如子对象的编号不能重复。

 

//<File>**********************************************************************
// Copyright (c) 2005
// 胡乐秋.
// 文件: Permit.hpp
// 内容: 许可者模式的泛型实现
// 使用: 被许可者:
//         按以下形式声明类并在每一个更改状态的命令之前调用IsPermit(EventID,Parameters)
//         class CChild : public HLQ_LIB::CPermitableT<CChild>
//         {
//            void ChangeState()
//            {
//                //检查是否允许改变状态
//                parameter_container_type Parameters;
//                Parameters.push_back(OldState);
//                Parameters.push_back(NewState);
//                if(!IsPermit(TEXT("ChangeState"),Parameters))
//                    return;
//                ...
//            }
//         };
//         许可者:
//         按以下形式声明类,并实现OnpermittedEvent函数
//         class CParent : public HLQ_LIB::CChild::permit_type
//         {
//            virtual bool OnPermittedAction(const HLQ_LIB::CChild::permitted_type* pMyClass,const CChild::event_id_type& EventID,const CChild::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]);
//                return true;  //return false;
//            }
//         };
// 初始化: 客户代码中应调用CChild或CParent的Attach方法建立起被许可者和许可者对象之间的绑定关系
// 注意: 在许可者或被许可者对象超出其寿命范围时,组件可自动取消两者之间的绑定关系.
//       注意当使用与父子对象之间时,应重载拷贝构造函数和赋值操作符,手工取消已有的绑定关系,增加新有的绑定关系
// 历史:
//    序号        修改时间        修改人        修改内容
//    1            2005/05/07        hlq            首次生成
//*********************************************************************</File>

//声明本头文件宏   
#ifndef _PERMIT_HPP
#define _PERMIT_HPP
   
//包含头文件
#ifdef _MSC_VER
#if _MSC_VER < 1300
#pragma warning(disable:4786)
#endif //_MSC_VER < 1300
#endif //_MSC_VER
#include <vector>
#include <cassert>

//开始名字空间
namespace HLQ_LIB
{

//<class>**********************************************************************
// 类名: CPermitT
// 目的: 许可者接口
//*********************************************************************</class>
template<class PermittedType>
class CPermitT
{
////类型声明
public:
    typedef typename PermittedType::permit_type                    permit_type;                //许可者类型
    typedef typename PermittedType::permitted_type                permitted_type;                //被许可者实际类型
    typedef typename PermittedType::event_id_type                event_id_type;                //被许可者事件ID类型,如字符串("删除对象")或int。缺省为字符串。
    typedef typename PermittedType::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 permitted_type*>                    permitted_container_type;
    typedef typename permitted_container_type::value_type        permitted_value_type;
    typedef typename permitted_container_type::iterator            permitted_iterator;
    typedef typename permitted_container_type::const_iterator    permitted_const_iterator;
    typedef typename permitted_container_type::size_type        permitted_size_type;
    typedef typename permitted_container_type::size_type        permitted_index_type;

////基本查询
public:
    //得到被许可者数量
    permitted_size_type GetPermittedCount() const {return m_Permitteds.size();}
    //检查是否已经绑定指定被许可者
    bool HasAttach(const permitted_type* pPermitted) const;
    //得到被许可者
    permitted_value_type GetPermitted(permitted_index_type Index) const{assert(Index<GetPermittedCount());return m_Permitteds[Index];}

////命令
public:
    //绑定被许可者(建立双向榜定)
    void Attach(const permitted_type* pPermitted);
    //取消被许可者绑定(取消双向榜定)
    void Detach(const permitted_type* pPermitted);
    //取消所有被许可者绑定(取消所有双向榜定)
    void DetachAllPermitteds();

////接口函数
protected:
    //被许可者行为通知消息
    friend permitted_type;
    virtual bool OnPermittedAction(const permitted_type* pPermitted,const event_id_type& ActionID,const parameter_container_type& Parameters) const= 0;

////构造、析构函数
public:
    //缺省构造函数
    CPermitT(){};
    //拷贝构造函数
    CPermitT(const CPermitT& rhs);
    //虚拟析构函数
    virtual ~CPermitT();
    //赋值操作俯重载
    CPermitT& operator=(const CPermitT& rhs);

////数据成员
private:
    permitted_container_type    m_Permitteds;
};

//检查是否已经绑定指定许可者
template <class permittedType>
inline bool CPermitT<permittedType>::HasAttach(const permitted_type* pPermitted) const
{
    //循环遍历每个许可者,检查是否已经注册
    for(permitted_const_iterator p=m_Permitteds.begin();p!=m_Permitteds.end();++p)
    {
        if(*p==pPermitted)
            return true;
    }
    return false;
}

//绑定被许可者(建立双向榜定)
template <class PermittedType>
inline void CPermitT<PermittedType>::Attach(const permitted_type* pPermitted)
{
    assert(!HasAttach(pPermitted));
    m_Permitteds.push_back(pPermitted);
    if(!pPermitted->HasAttach(this))
        (const_cast<permitted_type*>(pPermitted))->Attach(this);
    assert(pPermitted->HasAttach(this));
    assert(HasAttach(pPermitted));
}

//取消被许可者绑定(取消双向榜定)
template <class PermittedType>
inline void CPermitT<PermittedType>::Detach(const permitted_type* pPermitted)
{
    assert(HasAttach(pPermitted));
    for(permitted_iterator p=m_Permitteds.begin();p!=m_Permitteds.end();++p)
    {
        if(*p==pPermitted)
        {
            m_Permitteds.erase(p);
            if(pPermitted->HasAttach(this))
                (const_cast<permitted_type*>(pPermitted))->Detach(this);
            break;
        }
    }
    assert(!pPermitted->HasAttach(this));
    assert(!HasAttach(pPermitted));
}

//取消所有被许可者绑定(取消所有双向榜定)
template <class PermittedType>
inline void CPermitT<PermittedType>::DetachAllPermitteds()
{
    //循环释放每一个被许可者
    while(GetPermittedCount()>0)
        Detach(m_Permitteds[0]);
}

//拷贝构造函数
template <class PermittedType>
inline CPermitT<PermittedType>::CPermitT(const CPermitT& rhs)
{
    for(permitted_const_iterator p=rhs.m_Permitteds.begin();p!=rhs.m_Permitteds.end();++p)
        Attach(*p);
}

//虚拟析构函数(取消所有双向榜定)
template <class PermittedType>
inline CPermitT<PermittedType>::~CPermitT()
{
    //清空所有被许可者
    DetachAllPermitteds();
}

//赋值操作俯重载
template <class PermittedType>
CPermitT<PermittedType>& CPermitT<PermittedType>::operator=(const CPermitT& rhs)
{
    if(&rhs!=this)
    {
        //清空所有被许可者
        DetachAllPermitteds();
        for(permitted_const_iterator p=rhs.m_Permitteds.begin();p!=rhs.m_Permitteds.end();++p)
            Attach(*p);
    }
    return *this;
}

//<class>**********************************************************************
// 类名: CPermitableT
// 目的: 可被许可者
// 参数: PermittedType            - 被许可者具体类型,即本类的派生类
//         EventIDType            - 被许可者事件ID类型,如字符串("删除对象")或int。缺省为字符串。
//         ParameterType            - 参数类型,常为变体如CComVariant、boost::any等。缺省为boost::any。
//         ParameterContainerType    - 参数容器类型,常为std::vector或std::list等。缺省为std::vector。
//*********************************************************************</class>
template <class PermittedType,class EventIDType=std::basic_string<TCHAR>,class ParameterType=boost::any,class ParameterContainerType=std::vector<ParameterType> >
class CPermitableT
{
////类型声明
public:
    typedef CPermitableT<PermittedType>                        permitted_type;
    typedef EventIDType                                        event_id_type;
    typedef ParameterType                                    parameter_type;
    typedef ParameterContainerType                            parameter_container_type;
    typedef CPermitT<permitted_type>                        permit_type;
    typedef std::vector<const permit_type*>                    permit_container_type;
    typedef typename permit_container_type::value_type        permit_value_type;
    typedef typename permit_container_type::iterator        permit_iterator;
    typedef typename permit_container_type::const_iterator    permit_const_iterator;
    typedef typename permit_container_type::size_type        permit_size_type;
    typedef typename permit_container_type::size_type        permit_index_type;

////基本查询
public:
    //得到许可者数量
    permit_size_type GetPermitCount() const {return m_Permits.size();}
    //检查是否已经绑定指定许可者
    bool HasAttach(const permit_type* pPermit) const;
    //得到许可者
    permit_value_type GetPermit(permit_index_type Index) const{assert(Index<GetPermitCount());return m_Permits[Index];}

////命令
public:
    //绑定许可者(建立双向榜定)
    void Attach(const permit_type* pPermit);
    //取消许可者绑定(取消双向榜定)
    void Detach(const permit_type* pPermit);
    //取消所有被许可者绑定(取消所有双向榜定)
    void DetachAllPermits();

////派生类调用函数
protected:
    //许可者许可结果
    bool IsPermit(const event_id_type& EventID,const parameter_container_type& Parameters=parameter_container_type()) const;

////构造、析构函数
public:
    //缺省构造函数
    CPermitableT(){};
    //拷贝构造函数
    CPermitableT(const CPermitableT& rhs);
    //虚拟析构函数
    virtual ~CPermitableT(void);
    //赋值操作俯重载
    CPermitableT& operator=(const CPermitableT& rhs);

////数据成员
private:
    permit_container_type    m_Permits;
};

//检查是否已经绑定指定许可者
template <class PermittedType,class EventIDType,class ParameterType,class ParameterContainerType>
inline bool CPermitableT<PermittedType,EventIDType,ParameterType,ParameterContainerType>::HasAttach(const permit_type* pPermit) const
{
    //循环遍历每个许可者,检查是否已经注册
    for(permit_const_iterator p=m_Permits.begin();p!=m_Permits.end();++p)
    {
        if(*p==pPermit)
            return true;
    }
    return false;
}

//绑定许可者(建立双向榜定)
template <class PermittedType,class EventIDType,class ParameterType,class ParameterContainerType>
inline void CPermitableT<PermittedType,EventIDType,ParameterType,ParameterContainerType>::Attach(const permit_type* pPermit)
{
    assert(!HasAttach(pPermit));
    m_Permits.push_back(pPermit);
    if(!pPermit->HasAttach(this))
        (const_cast<permit_type*>(pPermit))->Attach(this);
    assert(HasAttach(pPermit));
    assert(pPermit->HasAttach(this));
}

//取消许可者绑定(取消双向榜定)
template <class PermittedType,class EventIDType,class ParameterType,class ParameterContainerType>
inline void CPermitableT<PermittedType,EventIDType,ParameterType,ParameterContainerType>::Detach(const permit_type* pPermit)
{
    assert(HasAttach(pPermit));
    for(permit_iterator p=m_Permits.begin();p!=m_Permits.end();++p)
    {
        if(*p==pPermit)
        {
            m_Permits.erase(p);
            if(pPermit->HasAttach(this))
                (const_cast<permit_type*>(pPermit))->Detach(this);
            break;
        }
    }
    assert(!HasAttach(pPermit));
    assert(!pPermit->HasAttach(this));
}

//取消所有被许可者绑定(取消所有双向榜定)
template <class PermittedType,class EventIDType,class ParameterType,class ParameterContainerType>
inline void CPermitableT<PermittedType,EventIDType,ParameterType,ParameterContainerType>::DetachAllPermits()
{
    //循环释放每一个许可者
    while(GetPermitCount()>0)
        Detach(m_Permits[0]);
}

//拷贝构造函数
template <class PermittedType,class EventIDType,class ParameterType,class ParameterContainerType>
inline CPermitableT<PermittedType,EventIDType,ParameterType,ParameterContainerType>::CPermitableT(const CPermitableT& rhs)
{
    for(permit_const_iterator p=rhs.m_Permits.begin();p!=rhs.m_Permits.end();++p)
        Attach(*p);
}

//虚拟析构函数
template <class PermittedType,class EventIDType,class ParameterType,class ParameterContainerType>
inline CPermitableT<PermittedType,EventIDType,ParameterType,ParameterContainerType>::~CPermitableT()
{
    //清空所有许可者
    DetachAllPermits();
}

//赋值操作俯重载
template <class PermittedType,class EventIDType,class ParameterType,class ParameterContainerType>
CPermitableT<PermittedType,EventIDType,ParameterType,ParameterContainerType>& CPermitableT<PermittedType,EventIDType,ParameterType,ParameterContainerType>::operator=(const CPermitableT& rhs)
{
    if(&rhs!=this)
    {
        //清空所有许可者
        DetachAllPermits();
        for(permit_const_iterator p=rhs.m_Permits.begin();p!=rhs.m_Permits.end();++p)
            Attach(*p);
    }
    return *this;
}

//许可者许可结果
template <class PermittedType,class EventIDType,class ParameterType,class ParameterContainerType>
inline bool CPermitableT<PermittedType,EventIDType,ParameterType,ParameterContainerType>::IsPermit(const event_id_type& EventID,const parameter_container_type& Parameters) const
{
    //循环遍历每一个许可者
    bool bPermit=true;
    for(permit_const_iterator p=m_Permits.begin();p!=m_Permits.end();++p)
    {
        bPermit&=(*p)->OnPermittedAction(this,EventID,Parameters);
        if(!bPermit)
            break;
    }
    return bPermit;
}

}//HLQ_LIB名字空间结束
#endif //假如未定义_PERMIT_HPP宏

胡乐秋

2010/8/3

http://blog.csdn.net/hlqyq

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