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