有一些業務邏輯,需要管理多個同樣類型的對象,並對外提供查詢,刪除等接口,在這些場合中,可以將被管理的對象稱為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類!!!