组合模式(C++)

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

  关于组合模式的定义有个关键词"树形",这个很关键,也很常见,如二叉树什么的。举个例子,如孝感城市,有教育部分和检察部门,孝感市下面的又有大悟县、红安县等县城,每个县城下面也有教育部分和检察部门,这个不就是一个树形结构吗(当然,还可以在县城叶子下面产生镇,镇也有教育部门和监察部门,这里仅仅是为了演示组合模式,叶子节点到县城这里就不在继续....)?

  用C++来实现,我们可以定义一个City的基类,里面定义两个add和diaplay函数,其中add用来添加city的对象,display主要是为了打印结果来看看"树形";再定义个一个指定的城市类,继承自City,并实现add和display方法;最后定义个教育部门类EducationBureau和监察部门类SupervisionBureau,并实现display方法(add方法不实现,我们假设已经到最下面的叶子节点)。说起来可能不大明白,我们用UML类图来看看呗:

再来来点代码就应该更有助于理解了:

#include <iostream>
#include <string>
#include <vector>
using namespace std;

class City//城市的基类
{
protected:
    string m_str;
public:
    City(string str):m_str(str){}
    virtual ~City(){}
    virtual void add(City* city){}
    virtual void display(int dep){}
};

class SpecifiedCity : public City //具体城市
{
private:
    vector<City*> m_list_city;
public:
    SpecifiedCity(string str):City(str){}
    ~SpecifiedCity(){}
    void add(City* city)
    {
        m_list_city.push_back(city);
    }
    void display(int dep)
    {
        for(int i=0; i<dep; i++)
        {
            cout<<"*";
        }
        cout<<m_str<<endl;
        vector<City*>::iterator iter;
        for(iter = m_list_city.begin(); iter != m_list_city.end(); iter++)
        {
            (*iter)->display(dep+2);//此处+2完全是为了表示树形结构,并无其他含义
        }
    }
};

class EducationBureau : public City //教育部
{
public:
    EducationBureau(string str):City(str){}
    virtual ~EducationBureau(){}
    void display(int dep)
    {
        for(int i=0; i<dep; i++)
        {
            cout<<"*";
        }
        cout<<m_str<<endl;
    }
};

class SupervisionBureau : public City//监察部
{
public:
    SupervisionBureau(string str):City(str){}
    virtual ~SupervisionBureau(){}
    void display(int dep)
    {
        for(int i=0; i<dep; i++)
        {
            cout<<"*";
        }
        cout<<m_str<<endl;
    }
};

int main(int argc, char** argv)
{
    City *pRoot =new SpecifiedCity("孝感市");
    City* pLeafA = new EducationBureau("教育部门");
    City* pLeafB = new SupervisionBureau("监察部门");
    pRoot->add(pLeafA);
    pRoot->add(pLeafB);
    pRoot->display(1);

    City *pRootA = new SpecifiedCity("大悟县");
    City* pLeafC = new EducationBureau("教育部门");
    City* pLeafD = new SupervisionBureau("监察部门");
    pRootA->add(pLeafC);
    pRootA->add(pLeafD);
    pRootA->display(4);

    City *pRootB = new SpecifiedCity("红安县");
    City* pLeafE = new EducationBureau("教育部门");
    City* pLeafF = new SupervisionBureau("监察部门");
    pRootB->add(pLeafE);
    pRootB->add(pLeafF);
    pRootB->display(4);

    delete pRoot; delete pLeafA; pLeafB;
    delete pRootA; delete pLeafC; pLeafD;
    delete pRootB; delete pLeafE; pLeafF;

    return 0;
}

要时还是不是很明白,那就看输出的"树形"结果吧:

   以上代码在VS2013上编译通过。

  以上的delete对象有点多哈,感觉有点笨。我开始想的使用智能指针来创建对象,但是最后添加时报错,调试了十来分钟没有弄好就没有弄,后面有时间再加上去,如果哪位大侠用智能指针实现了,麻烦发给我看看,我也想学习学习...........

posted @ 2018-02-12 14:00  1点er执着  阅读(327)  评论(0编辑  收藏  举报