有一些業務邏輯,需要管理多個同樣類型的對象,並對外提供查詢,刪除等接口,在這些場合中,可以將被管理的對象稱為Entity,管理Entity的類自然就叫做Entity_Manager,當以這樣的方式組織層級對象時,很直觀,而且項目的風格統一,每個人一旦熟悉了這種方式,理解別人寫的Entity_Manager就很輕松。根據以往的項目經驗,我自己實現了Entity和Entity_Manager類,代碼如下:
#ifndef __ENTITY_H__
#define __ENTITY_H__
#include <string>
#include <map>
typedef unsigned int uint32;
class Entity
{
protected:
Entity()
{
m_id = 0;
}
public:
virtual ~Entity()
{
}
void id(uint32 _id)
{
m_id = _id;
}
uint32 id() const
{
return m_id;
}
void name(std::string _name)
{
m_name = _name;
}
std::string name() const
{
return m_name;
}
private:
uint32 m_id;
std::string m_name;
};
//對所有子元素進行回調
template<typename Concrete_Entity>
class Entity_Exec
{
public:
Entity_Exec()
{
}
virtual ~Entity_Exec()
{
}
virtual bool exec(Concrete_Entity *entity) = 0;
virtual bool can_delete(Concrete_Entity *entity) const
{
return true;
}
};
class Guard_Ref
{
public:
Guard_Ref(bool &val) : m_val(val)
{
m_val = true;
}
~Guard_Ref()
{
m_val = false;
}
bool &m_val;
};
template<typename Key>
class Entity_Map
{
protected:
Entity_Map()
{
m_in_iteration = false;
}
~Entity_Map()
{
}
//是否正在迭代中, 用於禁止在迭代map時進行刪除迭代器等操作
bool in_iteration() const
{
return m_in_iteration;
}
bool add_entity(Key key, Entity *entity)
{
if(in_iteration())
{
return false;
}
if(m_entity_map.find(key) != m_entity_map.end())
{
return false;
}
m_entity_map[key] = entity;
return true;
}
Entity* get_entity(Key key) const
{
typename std::map<Key, Entity*>::const_iterator iter = m_entity_map.find(key);
if(iter == m_entity_map.end())
{
return NULL;
}
return iter->second;
}
uint32 size() const
{
return m_entity_map.size();
}
bool empty() const
{
return m_entity_map.empty();
}
void clear()
{
if(!in_iteration())
{
m_entity_map.clear();
}
}
template<typename Concrete_Entity>
void exec_all(Entity_Exec<Concrete_Entity> &cb)
{
Guard_Ref guard(m_in_iteration);
for(typename std::map<Key, Entity*>::iterator iter = m_entity_map.begin(); iter != m_entity_map.end(); ++iter)
{
cb.exec(static_cast<Concrete_Entity*>(iter->second));
}
}
template<typename Concrete_Entity>
bool exec_until(Entity_Exec<Concrete_Entity> &cb)
{
Guard_Ref guard(m_in_iteration);
for(typename std::map<Key, Entity*>::iterator iter = m_entity_map.begin(); iter != m_entity_map.end(); ++iter)
{
if(cb.exec(static_cast<Concrete_Entity*>(iter->second)))
{
return true;
}
}
return false;
}
template<typename Concrete_Entity>
bool exec_if(Entity_Exec<Concrete_Entity> &cb)
{
bool ret = false;
Guard_Ref guard(m_in_iteration);
for(typename std::map<Key, Entity*>::iterator iter = m_entity_map.begin(); iter != m_entity_map.end(); ++iter)
{
Concrete_Entity *concrete_entity = static_cast<Concrete_Entity*>(iter->second);
if(cb.exec(concrete_entity))
{
ret = true;
}
}
return ret;
}
void delete_entity(Key key)
{
if(!in_iteration())
{
m_entity_map.erase(key);
}
}
template<typename Concrete_Entity>
bool delete_if(Entity_Exec<Concrete_Entity> &cb, std::vector<Entity*> &del_vec)
{
if(in_iteration())
{
return false;
}
Guard_Ref guard(m_in_iteration);
bool ret = false;
for(typename std::map<Key, Entity*>::iterator iter = m_entity_map.begin(); iter != m_entity_map.end(); ++iter)
{
Concrete_Entity *concrete_entity = static_cast<Concrete_Entity*>(iter->second);
if(cb.can_delete(concrete_entity))
{
ret = true;
del_vec.push_back(concrete_entity);
}
}
return ret;
}
private:
std::map<Key, Entity*> m_entity_map;
bool m_in_iteration;
};
class KEY_UINT32 : protected Entity_Map<uint32>
{
protected:
typedef Entity_Map<uint32> Super;
KEY_UINT32()
{
}
bool add_entity(Entity *entity)
{
return Super::add_entity(entity->id(), entity);
}
void delete_entity(Entity *entity)
{
Super::delete_entity(entity->id());
}
};
class KEY_STRING : protected Entity_Map<std::string>
{
protected:
typedef Entity_Map<std::string> Super;
KEY_STRING()
{
}
bool add_entity(Entity *entity)
{
return Super::add_entity(entity->name(), entity);
}
void delete_entity(Entity *entity)
{
Super::delete_entity(entity->name());
}
};
//占位
template<int>
class KEY_NONE
{
protected:
KEY_NONE()
{
}
void clear()
{
}
bool add_entity(Entity *entity)
{
return true;
}
void delete_entity(Entity *entity)
{
}
};
//提取基類的trait
template<typename T>
struct Get_Super
{
};
template<>
struct Get_Super<uint32>
{
typedef KEY_UINT32 Super;
};
template<>
struct Get_Super<std::string>
{
typedef KEY_STRING Super;
};
template<typename Concrete_Entity, typename Super1, typename Super2 = KEY_NONE<1> >
class Entity_Manager : private Super1, private Super2
{
protected:
Entity_Manager()
{
}
bool add_entity(Entity *entity)
{
if(!Super1::add_entity(entity))
{
return false;
}
if(!Super2::add_entity(entity))
{
Super1::delete_entity(entity);
return false;
}
return true;
}
bool delete_if(Entity_Exec<Concrete_Entity> &cb)
{
std::vector<Entity*> del_vec;
if(!Super1::delete_if(cb, del_vec))
{
return false;
}
for(std::vector<Entity*>::iterator iter = del_vec.begin(); iter != del_vec.end(); ++iter)
{
Concrete_Entity *concrete_entity = static_cast<Concrete_Entity*>(concrete_entity);
delete_entity(concrete_entity);
cb.exec(concrete_entity);
}
return true;
}
void delete_all(Entity_Exec<Concrete_Entity> &cb)
{
exec_all(cb);
clear();
}
template<typename Key>
Concrete_Entity* get_entity(Key key) const
{
return static_cast<Concrete_Entity*>(Get_Super<Key>::Super::get_entity(key));
}
void delete_entity(Entity *entity)
{
Super1::delete_entity(entity);
Super2::delete_entity(entity);
}
public:
uint32 size() const
{
return Super1::size();
}
bool empty() const
{
return Super1::empty();
}
void clear()
{
Super1::clear();
Super2::clear();
}
bool exec_until(Entity_Exec<Concrete_Entity> &cb)
{
return Super1::exec_until(cb);
}
bool exec_if(Entity_Exec<Concrete_Entity> &cb)
{
return Super1::exec_if(cb);
}
void exec_all(Entity_Exec<Concrete_Entity> &cb)
{
Super1::exec_all(cb);
}
};
#endif 我實現的Entity_Manager支持兩種類型建立索引來查找被管理的對象,一種按名字查找,一種按數字id查找,具體功能模塊可以根據需要以不同的模板參數來繼承Entity_Manager來管理自己的對象。這裡簡單給出一個例子來講解如何使用Entity_Manager類,假如項目中有很多的任務,需要建立一個任務管理器來管理任務,我們將任務抽象成Task類,任務管理器抽象為Task_Manager類,如果我希望按id來管理我的任務,Task_Manager類定義如下:
class Task_Manager : public Entity_Manager<Task, KEY_UINT32>
{
public:
Task* get_task(uint32 task_id) const
{
return get_entity(task_id);
}
bool add_task(const Task *task)
{
return add_entity(task);
}
void delete_task(const Task *task)
{
delete_entity(task);
}
void print_all_task_name()
{
struct CB : Entity_Exec<Task>
{
bool exec(Task *task)
{
print(task->name());
}
}
CB cb;
exec_all(cb);
}
};
只要繼承Entity_Manager類後,Task_Manager類就具備了管理多個Task類的能力,支持對task的查詢,刪除,遍歷等操作,而且在Entity_Manager的基類中實現了一種保護機制,就是在迭代的時候,不會出現導致迭代器失效的操作,因此在業務功能開發中,可以大膽地使用Entity_Manger管理類。如果項目中都以同樣的方式來管理層級對象,那麼項目的風格很統一,項目裡每個開發人員也能夠最快的理解別人寫的管理器,於項目也是大有好處。所以歡迎在你的項目中也使用Entity_Manager類!!!