结构模式->组合模式

       组合模式(Composite Pattern):组合多个对象形成树形结构以表示具有“整体—部分”关系的层次结构。组合模式对单个对象(即叶子对象)和组合对象(即容

器对象)的使用具有一致性,组合模式又可以称为“整体—部分”(Part-Whole)模式,它是一种对象结构型模式。

将对象组合成树形结构以表示部分-整体的层次结构,组合模式使得用户对单个对象跟组合对象使用具有一致性。

注意两个字“树形”。这种树形结构在现实生活中随处可见,比如一个集团公司,它有一个母公司,下设很多家子公司。不管是母公司还是子公司,都有各自直属的财务部、人力资源部、销售部等。对于母公司来说,不论是子公司,还是直属的财务部、人力资源部,都是它的部门。整个公司的部门拓扑图就是一个树形结构。

      下面给出组合模式的UML图。从图中可以看到,FinanceDepartment、HRDepartment两个类作为叶结点,因此没有定义添加函数。而ConcreteCompany类可以作为中间结点,所以可以有添加函数。那么怎么添加呢?这个类中定义了一个链表,用来放添加的元素。

       相应的代码实现为:

class Company    
{  
public:  
    Company(string name) { m_name = name; }  
    virtual ~Company(){}  
    virtual void Add(Company *pCom){}  
    virtual void Show(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 Show(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)->Show(depth + 2);  
    }  
private:  
    list<Company *> m_listCompany;  
};  
//具体的部门,财务部  
class FinanceDepartment : public Company   
{  
public:  
    FinanceDepartment(string name):Company(name){}  
    virtual ~FinanceDepartment() {}  
    virtual void Show(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 Show(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);  
  
    //分公司A  
    Company *mid1 = new ConcreteCompany("分公司A");  
    Company *leaf3=new FinanceDepartment("财务部");  
    Company *leaf4=new HRDepartment("人力资源部");  
    mid1->Add(leaf3);  
    mid1->Add(leaf4);  
    root->Add(mid1);  
    //分公司B  
    Company *mid2=new ConcreteCompany("分公司B");  
    FinanceDepartment *leaf5=new FinanceDepartment("财务部");  
    HRDepartment *leaf6=new HRDepartment("人力资源部");  
    mid2->Add(leaf5);  
    mid2->Add(leaf6);  
    root->Add(mid2);  
    root->Show(0);  
  
    delete leaf1; delete leaf2;  
    delete leaf3; delete leaf4;  
    delete leaf5; delete leaf6;   
    delete mid1; delete mid2;  
    delete root;  
    return 0;  
}  
    上面的实现方式有缺点,就是内存的释放不好,需要客户自己动手,非常不方便。有待改进,比较好的做法是让ConcreteCompany类来释放。因为所有的指针都是存在ConcreteCompany类的链表中。C++的麻烦,没有垃圾回收机制。

其实组合模式类似与 数据结构中的树形式 存储  以前我们做的是简单的有序二叉树 存储仅仅是int  其实可以将int 抽象化为一个对象 放置对象 也可以。
     透明方式 跟 安全方式   

关注公众号 海量干货等你
原文地址:https://www.cnblogs.com/sowhat1412/p/12734428.html