程序師世界是廣大編程愛好者互助、分享、學習的平台,程序師世界有你更精彩!
首頁
編程語言
C語言|JAVA編程
Python編程
網頁編程
ASP編程|PHP編程
JSP編程
數據庫知識
MYSQL數據庫|SqlServer數據庫
Oracle數據庫|DB2數據庫
 程式師世界 >> 編程語言 >> C語言 >> C++ >> C++入門知識 >> 設計模式C++描述----11.組合(Composite)模式

設計模式C++描述----11.組合(Composite)模式

編輯:C++入門知識

上一篇:http://www.BkJia.com/kf/201205/132469.html

一. 舉例


這個例子是書上的,假設有一個公司的組結結構如下:

 \


 

它的結構很像一棵樹,其中人力資源部和財務部是沒有子結點的,具體公司才有子結點。

而且最關健的是,它的每一層結構很相似。


代碼實現如下:
[cpp] view plaincopyprint?//公司類,提供接口  
class Company     
{   
public:   
    Company(string name) 
    { 
        m_name = name; 
    }   
     
    virtual ~Company() 
    {}   
     
    virtual void Add(Company *pCom) 
    {}   
     
    virtual void Display(int depth) 
    {} 
 
protected: 
    string m_name;   
}; 
 
//具體公司  
class ConcreteCompany : public Company     
{   
public:   
    ConcreteCompany(string name): Company(name) 
    {} 
 
    virtual ~ConcreteCompany() 
    {} 
 
    //增加子樹或葉子  
    void Add(Company *pCom) 
    { 
        m_listCompany.push_back(pCom); 
    } 
     
    //顯示  
    void Display(int depth) 
    { 
        for(int i = 0;i < depth; i++) 
        { 
            cout<<"-";   
         
        } 
         
        cout<< m_name << endl; 
         
        list<Company *>::iterator iter = m_listCompany.begin();   
         
        for(; iter != m_listCompany.end(); iter++) //顯示下層結點    
        {     
            (*iter)->Display(depth + 2); 
        } 
    } 
 
private:   
    list<Company *> m_listCompany;   
};   
 
//具體的部門,財務部    
class FinanceDepartment : public Company    

public:   
    FinanceDepartment(string name):Company(name) 
    {}   
     
    virtual ~FinanceDepartment() 
    {}   
     
    //只需顯示,無限添加函數,因為已是葉結點    
    virtual void Display(int depth) 
    {   
        for(int i = 0; i < depth; i++)   
            cout<<"-";   
         
        cout<< m_name << endl; 
    } 
};   
 
//具體的部門,人力資源部    
class HRDepartment :public Company     
{   
public:   
    HRDepartment(string name):Company(name) 
    {} 
     
    virtual ~HRDepartment() 
    {} 
     
    //只需顯示,無限添加函數,因為已是葉結點    
    virtual void Display(int depth) 
    { 
        for(int i = 0; i < depth; i++)   
        { 
            cout<<"-"; 
        } 
        cout<< m_name << endl;   
    }   
}; 
 
//////////////////////////////////////////////////////////////////////////  
//測試代碼  
int main() 

    Company *root = new ConcreteCompany("總公司");   
    Company *leaf1=new FinanceDepartment("財務部");   
    Company *leaf2=new HRDepartment("人力資源部");   
    root->Add(leaf1);   
    root->Add(leaf2);   
  
    //華東分公司  
    Company *mid1 = new ConcreteCompany("華東分公司");   
    Company *leaf3=new FinanceDepartment("華東分公司財務部");   
    Company *leaf4=new HRDepartment("華東分公司人力資源部");   
    mid1->Add(leaf3); 
    mid1->Add(leaf4); 
    root->Add(mid1); 
     
    //南京辦事處  
    Company *mid2=new ConcreteCompany("南京辦事處");   
    FinanceDepartment *leaf5=new FinanceDepartment("南京辦事處財務部");   
    HRDepartment *leaf6=new HRDepartment("南京辦事處人力資源部");   
    mid2->Add(leaf5); 
    mid2->Add(leaf6); 
    root->Add(mid2); 
  
    //杭州辦事處  
    Company *mid3=new ConcreteCompany("杭州辦事處");   
    FinanceDepartment *leaf7=new FinanceDepartment("杭州辦事處財務部");   
    HRDepartment *leaf8=new HRDepartment("杭州辦事處人力資源部");   
    mid3->Add(leaf7);   
    mid3->Add(leaf8);   
    mid2->Add(mid3); 
 
    root->Display(0); 
 
    delete leaf1; 
    delete leaf2;   
    delete leaf3; 
    delete leaf4;   
    delete leaf5; 
    delete leaf6; 
    delete leaf7; 
    delete leaf8;   
    delete mid1; 
    delete mid2;   
    delete root;   
     
    return 0; 

//公司類,提供接口
class Company   

public: 
    Company(string name)
    {
        m_name = name;
    } 
   
    virtual ~Company()
    {} 
   
    virtual void Add(Company *pCom)
    {} 
   
    virtual void Display(int depth)
    {}

protected:
    string m_name; 
};

//具體公司 www.2cto.com
class ConcreteCompany : public Company   

public: 
    ConcreteCompany(string name): Company(name)
    {}

    virtual ~ConcreteCompany()
    {}

    //增加子樹或葉子
    void Add(Company *pCom)
    {
        m_listCompany.push_back(pCom);
    }
   
    //顯示
    void Display(int depth)
    {
        for(int i = 0;i < depth; i++)
        {
            cout<<"-"; 
       
        }
       
        cout<< m_name << endl;
       
        list<Company *>::iterator iter = m_listCompany.begin(); 
       
        for(; iter != m_listCompany.end(); iter++) //顯示下層結點 
        {   
            (*iter)->Display(depth + 2);
        }
    }

private: 
    list<Company *> m_listCompany; 
}; 

//具體的部門,財務部 
class FinanceDepartment : public Company  
{
public: 
    FinanceDepartment(string name):Company(name)
    {} 
   
    virtual ~FinanceDepartment()
    {} 
   
    //只需顯示,無限添加函數,因為已是葉結點 
    virtual void Display(int depth)
    { 
        for(int i = 0; i < depth; i++) 
            cout<<"-"; 
       
        cout<< m_name << endl;
    }
}; 

//具體的部門,人力資源部 
class HRDepartment :public Company   

public: 
    HRDepartment(string name):Company(name)
    {}
   
    virtual ~HRDepartment()
    {}
   
    //只需顯示,無限添加函數,因為已是葉結點 
    virtual void Display(int depth)
    {
        for(int i = 0; i < depth; i++) 
        {
            cout<<"-";
        }
        cout<< m_name << endl; 
    } 
};

//////////////////////////////////////////////////////////////////////////
//測試代碼
int main()
{
    Company *root = new ConcreteCompany("總公司"); 
    Company *leaf1=new FinanceDepartment("財務部"); 
    Company *leaf2=new HRDepartment("人力資源部"); 
    root->Add(leaf1); 
    root->Add(leaf2); 
 
    //華東分公司
    Company *mid1 = new ConcreteCompany("華東分公司"); 
    Company *leaf3=new FinanceDepartment("華東分公司財務部"); 
    Company *leaf4=new HRDepartment("華東分公司人力資源部"); 
    mid1->Add(leaf3);
    mid1->Add(leaf4);
    root->Add(mid1);
   
    //南京辦事處
    Company *mid2=new ConcreteCompany("南京辦事處"); 
    FinanceDepartment *leaf5=new FinanceDepartment("南京辦事處財務部"); 
    HRDepartment *leaf6=new HRDepartment("南京辦事處人力資源部"); 
    mid2->Add(leaf5);
    mid2->Add(leaf6);
    root->Add(mid2);
 
    //杭州辦事處
    Company *mid3=new ConcreteCompany("杭州辦事處"); 
    FinanceDepartment *leaf7=new FinanceDepartment("杭州辦事處財務部"); 
    HRDepartment *leaf8=new HRDepartment("杭州辦事處人力資源部"); 
    mid3->Add(leaf7); 
    mid3->Add(leaf8); 
    mid2->Add(mid3);

    root->Display(0);

    delete leaf1;
    delete leaf2; 
    delete leaf3;
    delete leaf4; 
    delete leaf5;
    delete leaf6;
    delete leaf7;
    delete leaf8; 
    delete mid1;
    delete mid2; 
    delete root; 
   
    return 0;
}
二. 說明

1. 上面公司的結構圖其實就是整體與部分的關系,而且的話整體與部分可以一致對待,因為有很多相似之處嘛。

2. 這棵樹有兩種幾能,要麼是棵葉,要麼是子棵。


其實這種模式就是組合模式。

三. 組合模式

定義:將對象組合成樹形結構以表示“部分-整體”的層次結構。組合使得用戶對單個對象和組合對象的使用具有一致性。

要注意兩點:

1. “樹形”,必須是一種層次結構,有可以向下延伸的分枝,也有不變的樹葉。

2. "一致性",也就是要具有很多相似性。

結構圖如下:

 \

component:主要是定義統一的接口,說白了也就是提取出相似性。

composite:定義分枝節點,也就是子樹。

leaf:定義葉節點,葉節點是沒有子節點的。

 


作者 lwbeyond

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