组合模式(Composite Pattern)

324 阅读2分钟

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

问题:在开发中,我们经常可能要递归构建树状的组合结构,Composite 模式则提供了很好的解决方案。

主要解决:它在我们树型结构的问题中,模糊了简单元素和复杂元素的概念,客户程序可以向处理简单元素一样来处理复杂元素,从而使得客户程序与复杂元素的内部结构解耦。

何时使用

  • 您想表示对象的部分-整体层次结构(树形结构)。
  • 您希望用户忽略组合对象与单个对象的不同,用户将统一地使用组合结构中的所有对象。

如何解决:树枝和叶子实现统一接口,树枝内部组合该接口。

关键代码:树枝内部组合该接口,并且含有内部属性 List,里面放 Component。

使用场景:部分、整体场景,如树形菜单,文件、文件夹的管理。

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

//接口抽象
class Component
{
public:
    Component(string name){
        m_name=name;
    }
    virtual ~Component(){}

public:
    virtual void Operation()=0;
    virtual void Add(const Component& ){}
    virtual void Remove(const Component& ){}
    virtual Component* GetChild(int ){
        return NULL;
    }

    string m_name;
};

class Composite:public Component
{
public:
    Composite(string name):Component(name){}
    ~Composite(){
        cout<<m_name<<" destructor..."<<endl;
        for (vector<Component *>::iterator it = comVec.begin();it!=comVec.end();++it){
            delete *it;
        }
    }

public:
    void Operation(){
        vector<Component*>::iterator comiter=comVec.begin();
        for (; comiter!=comVec.end();comiter++)
        {
            (*comiter)->Operation();
        }
    }
    void Add(Component* com){
        comVec.push_back(com);
    }
    void Remove(Component* com){
        for (vector<Component*>::iterator it = comVec.begin();it!=comVec.end();it++){
            if (*it == com){
                delete *it;
                *it=NULL;

                comVec.erase(it);
                break;
            }
        }
    }
    Component* GetChild(int index){
        return comVec[index];
    }

private:
    vector<Component*> comVec;
};


class Leaf:public Component
{
public:
    Leaf(string name):Component(name){
    }
    ~Leaf(){
        cout<<m_name<<" destructor..."<<endl;
    }
    void Operation(){
        cout<<"Leaf("<<m_name<<") operation......"<<endl;
    }
};

int main()
{
    Composite* root = new Composite("root");

    Leaf* la=new Leaf("leaf a");
    Leaf* lb=new Leaf("leaf b");
    Leaf* laa=new Leaf("leaf aa");

    Composite* coma = new Composite("com a");
    Composite* comb = new Composite("com b");
    coma->Add(la);
    coma->Add(lb);
    comb->Add(laa);

    root->Add(coma);
    root->Add(comb);
//    coma->Operation();
    root->Operation();

//    Component* l_a=coma->GetChild(0);
//    l_a->Operation();
    delete root;

    return 0;
}