程序師世界是廣大編程愛好者互助、分享、學習的平台,程序師世界有你更精彩!
首頁
編程語言
C語言|JAVA編程
Python編程
網頁編程
ASP編程|PHP編程
JSP編程
數據庫知識
MYSQL數據庫|SqlServer數據庫
Oracle數據庫|DB2數據庫
 程式師世界 >> 編程語言 >> C語言 >> C++ >> C++入門知識 >> c++組合對象管理

c++組合對象管理

編輯:C++入門知識

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

  1. 上一頁:
  2. 下一頁:
Copyright © 程式師世界 All Rights Reserved