编程语言

img dhunter

Party - Organization - Employee - Party模式的C++实现

发表于2004/10/12 10:29:00  972人阅读

一段c++builder下的老代码。
用组合模式来实现组织结构,singleton的OrgTreeRepository来保存所有对象。
稍有问题的地方就是一部分构造界面的代码渗入到了实体对象中--MakeChildTreeView(),这个因为用它来初始化界面中的人员组织树简直是太干净了,实在没法抵挡这种诱惑。其它的业务方法差不多是相同的逻辑,去掉了。


#ifndef OrganizationH
#define OrganizationH
#include <Classes.hpp>
#include <vector>
#include <list>
#include "Global/Global.h"
#include "mylib/mylib/Object_Manager.h"
#include "DataModule/PersistHome.h"
#include <memory>
#include "DataModule/Persist.h"
#include "mylib/mylog.h"
using namespace std;
using namespace mylib;
using namespace planmanage;
//---------------------------------------------------------------------------
class Party
{
public:
    virtual void MakeChildTreeView(TTreeView * tree, TTreeNode* fnode)=0;
    void SetName(const String &arg)
    {
        this->m_name=arg;
    }
    const String GetName()
    {
        return m_name;
    }
    virtual bool IsLeaf()=0;
    virtual Party* FindByName(const String & name)=0;
    virtual Party* FindById(const String & id) =0;
    virtual void AddChild(Party* party)=0;
    virtual String GetParentId()=0;
    virtual ~Party(){}
    virtual void Dump()=0;
    virtual void DumpChild()=0;
    void SetParent(Party* arg)
    {
        m_parent = arg;
    }
    Party* GetParent()
    {
        return m_parent;
    }
    int GetLevel()
    {
        int ret=0;
        Party * cursor = this->GetParent();
        while(cursor)
        {
            cursor = cursor->GetParent();
            ret++;
        }
        return ret;
    }
protected:
    TTreeNode* AddTreeViewNode(TTreeView *tree, TTreeNode* fnode)
    {
        TTreeNode* node = tree->Items->AddChildObject(fnode,m_name,this);
        node->ImageIndex = IsLeaf() ? 1 : 0;
        return node;
    }
    String m_name;
    Party* m_parent;
};
class Organization : public Party, public Persist<>
{
public:
    Organization()
    {
    }
    void MakeChildTreeView(TTreeView * tree, TTreeNode* fnode)
    {
        TTreeNode* node = AddTreeViewNode(tree,fnode);
        for(size_t i=0; i<m_children.size(); i++)
        {
            m_children[i]->MakeChildTreeView(tree, node);
        }
    }
    bool IsLeaf()
    {
        return false;
    }
    Party* FindByName(const String & name)
    {
        if(this->GetName()==name) return this;
        else
        {
            for(size_t i=0;i<m_children.size();i++)
            {
                Party* ret = m_children[i]->FindByName(name);
                if(ret) return ret;
            }
        }
        return NULL;
    }
    Party* FindById(const String & id)
    {
        if(this->GetId()==id) return this;
        else
        {
            for(size_t i=0;i<m_children.size();i++)
            {
                Party* ret = m_children[i]->FindById(id);
                if(ret) return ret;
            }
        }
        return NULL;
    }
    void AddChild(Party* party)
    {
        m_children.push_back(party);
    }
    String GetParentId()
    {
        return m_pid;
    }
    ~Organization()
    {
        ClearContainer(&m_children);
    }
    void Dump()
    {
        log()<<"Dep: "+string(m_name.c_str())<<endl;
        log()<<"-------------"<<endl;
        for(size_t i=0; i<m_children.size();i++)
        {
            m_children[i]->Dump();
        }
        log()<<"-------------"<<endl;
    }
    void DumpChild()
    {
        log()<<"all children"<<endl;
        for(size_t i=0; i<m_children.size();i++)
        {
            log()<<m_children[i]->GetName().c_str()<<endl;
        }
    }
protected:
    void Bind()
    {
        BindTable("DOCMAN.DEPARTMENT","ID");
        BindField<StringBinding>(m_name, "MANE");
        BindField<StringBinding>(m_pid,"PARENT_ID");
    }
private:
    vector<Party *> m_children;
    String m_pid;
};
class Employee : public Party, public Persist<false>
{
public:
    void MakeChildTreeView(TTreeView * tree, TTreeNode* fnode)
    {
        AddTreeViewNode(tree,fnode);
    }
    bool IsLeaf()
    {
        return true;
    }
    Party* FindByName(const String & name)
    {
        if(this->GetName()==name)
            return this;
        else
            return NULL;
    }
    Party* FindById(const String & id)
    {
        if(this->GetId()==id)
            return this;
        else
            return NULL;
    }
    void AddChild(Party* party)
    {
        //do nothing
    }
    String GetParentId()
    {
        return m_depId;
    }
    void Dump()
    {
        log()<<"Staff: "+string(m_name.c_str())<<endl;
    }
    void DumpChild()
    {
        log()<<"leaf node"<<endl; 
    }
protected:
    void Bind()
    {
        BindTable("DOCMAN.STAFFINFO", "STAFFNO");
        BindField < StringBinding > (m_name, "STAFFNAME");
        BindField < StringBinding > (m_depId, "DEPARTNO");
    }
private:
    String m_depId;
};
//singlton
class OrgTreeRepository : public Cleanup
{
public:
    static OrgTreeRepository * GetInstance()
    {
        if(!m_instance)
        {
            m_instance = new OrgTreeRepository();
            mylib::Object_Manager::at_exit(m_instance);
        }
        return m_instance;
    }
    Party * GetTreeRoot()
    {
        return m_root;
    }
    Party * FindByName(const String &name)
    {
        return m_root->FindByName(name);
    }
    Party * FindById(const String &id)
    {
        return m_root->FindById(id);
    }
    Organization * GetJY()
    {
        return dynamic_cast<Organization*>(m_root->FindById(JY_DEP_ID));
    }
    Organization * GetZZ()
    {
        return dynamic_cast<Organization*>(m_root->FindById(ZZ_DEP_ID));
    }
    Organization * GetSB()
    {
        return dynamic_cast<Organization*>(m_root->FindById(SB_DEP_ID));
    }
    Organization * GetHZ()
    {
        return dynamic_cast<Organization*>(m_root->FindById(HZ_DEP_ID));
    }
    Organization * GetRootOrg()
    {
        return dynamic_cast<Organization*>(m_root);
    }
private:
    static OrgTreeRepository * m_instance;
    OrgTreeRepository()
    {
        InitOrgTree();
    }
    ~OrgTreeRepository()
    {
        delete m_root;
    }
    Party * m_root;
    void InitRootNode()
    {
        Organization * org= new Organization();
        org->SetId(0);
        org->SetParent(NULL);
        org->Load();
        m_root = org;
    }
    void InitOrgTree()
    {
        InitRootNode();
        auto_ptr< list<Organization*> > orgs(
                PersistHome < Organization, list<Organization*> >::SelectByFilter("id <> 0")
                );
        AddKindNodes(orgs.get());
        ClearContainer(orgs.get());
        auto_ptr< list<Employee*> > emps(PersistHome < Employee, list<Employee*> >::SelectAll());
        AddKindNodes(emps.get());
        ClearContainer(emps.get());
    }
    template < typename CollectionType>
    void AddKindNodes(CollectionType *collection)
    {
        typedef CollectionType::iterator Iterator;
        if(!collection) return;
        //循环取出,直至大小不再变化
        size_t vane=0;
        while(!collection->empty()&& collection->size()!=vane)
        {
            vane=collection->size();
            for(Iterator i=collection->begin(); i!=collection->end(); i++)
            {
                Party* parent = m_root->FindById((*i)->GetParentId());
                if(parent)
                {
                    parent->AddChild(*i);
                    (*i)->SetParent(parent);
                    i=collection->erase(i);
                }
            }
        }
    }
};
#endif
阅读全文
0 0

相关文章推荐

img
取 消
img