组合(composite)模式

定义

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

组合模式(Composite)将小对象组合成树形结构,使用户操作组合对象如同操作一个单个对象。组合模式定义了“部分-整体”的层次结构,基本对象可以被组合成更大的对象,而且这种操作是可重复的,不断重复下去就可以得到一个非常大的组合对象,但这些组合对象与基本对象拥有相同的接口,因而组合是透明的,用法完全一致。

代码:

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

class IFile
{
public:
    virtual void display() = 0;
    virtual int add(IFile *ifile) = 0;
    virtual int remove(IFile *ifile) = 0;
    virtual list<IFile*> *getChild() = 0;
};

class File : public IFile
{
public:
    File(string name) :_name(name){}
    virtual void display()
    {
        cout << _name << endl;
    }

    virtual int add(IFile *ifile)
    {
        return -1;
    }
    
    virtual int remove(IFile *ifile)
    {
        return -1;
    }

    virtual list<IFile*>* getChild()
    {
        return NULL;
    }

private:
    string _name;
};

class Dir : public IFile
{
public:
    Dir(string name)
    {
        _name = name;
        _list.clear();
    }

    virtual void display()
    {
        cout << _name << endl;
    }

    virtual int add(IFile *ifile)
    {
        _list.push_back(ifile);
        return 0;
    }

    virtual int remove(IFile *ifile)
    {
        _list.remove(ifile);
        return 0;
    }

    virtual list<IFile*> *getChild()
    {
        return &_list;
    }

private:
    string _name;
    list<IFile*> _list;
};


void showTree(IFile *root, int level)
{
    if (root == NULL || level < 0)
        return;

    for (int i = 0; i < level; ++i)
    {
        cout << "	";
    }
    
    // 显示根节点
    root->display();

    // 判断是否为目录
    // 如果不是目录,为文件(返回值为NULL),直接返回
    //否则遍历目录
    list<IFile*> *file_list = root->getChild();
    if (file_list == NULL)
        return;

    for (auto it = file_list->begin(); it != file_list->end(); ++it)
    {
        // 普通文件
        if ((*it)->getChild() == NULL)
        {
            for (int i = 0; i <= level; ++i)
            {
                cout << "	";
            }
            // 显示普通文件
            (*it)->display();
        }
        else  //目录
        {
            // 递归 显示该目录下的文件
            showTree(*it, level + 1);
        }
    }
}


void test()
{
    IFile *root = new Dir("/");
    IFile *aa = new Dir("aa");
    IFile *bb = new Dir("bb");
    IFile *cc = new Dir("cc");
    IFile *dd = new File("dd");
    IFile *ee = new File("ee");
    IFile *ff = new File("ff");
    IFile *gg = new File("gg");
    IFile *hh = new Dir("hh");
    cc->add(gg);
    cc->add(hh);

    aa->add(cc);
    aa->add(dd);
    bb->add(ee);
    bb->add(ff);
    root->add(aa);
    root->add(bb);
    

    showTree(root, 0);

}


int main()
{
    test();
    cin.get();
    return 0;
}

效果:

原文地址:https://www.cnblogs.com/hupeng1234/p/6797046.html