结构型模式 组合模式

结构型模式 组合模式

Component (树形结构的节点抽象)
  - 为所有的对象定义统一的接口(公共属性,行为等的定义)
  - 提供管理子节点对象的接口方法
  - [可选]提供管理父节点对象的接口方法

Leaf (树形结构的叶节点)
  Component的实现子类

Composite(树形结构的枝节点)
  Component的实现子类

适用于: 单个对象和组合对象的使用具有一致性。将对象组合成树形结构以表示“部分--整体”

/**
 * 结构型模式 组合模式
 * Composite模式也叫组合模式,是构造型的设计模式之一。通过递归手段来构造树形的对象结构,并可以通过一个对象来访问整个对象树。
 *
 */

#define _CRT_SECURE_NO_WARNINGS

#include <iostream>
#include <string>
#include <list>

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

class File: public IFile
{
public:
    File(std::string name)
    {
        m_list = nullptr;
        m_name = "";
        m_name = name;
    }
    ~File()
    {
        if (m_list != nullptr)
        {
            delete m_list;
            m_list = nullptr;
        }
    }
    virtual void display() override
    {
        std::cout << "File m_name: " << m_name << std::endl;
    }
    virtual int add(IFile *ifile) override
    {
        return -1;
    }
    virtual int remove(IFile *ifile) override
    {
        return -1;
    }
    virtual std::list<IFile *> * getChild() override
    {
        return nullptr;
    }
private:
    std::list<IFile *> * m_list;
    std::string m_name;
};

class Folder: public IFile
{
public:
    Folder(std::string name)
    {
        m_name = "";
        m_name = name;
        m_list = new std::list<IFile *>;
        m_list->clear();
    }
    ~Folder()
    {
        if (m_list != nullptr)
        {
            delete m_list;
            m_list = nullptr;
        }
    }
    virtual void display() override
    {
        std::cout << "Folder m_name: " << m_name << std::endl;
    }
    virtual int add(IFile *ifile) override
    {
        m_list->push_back(ifile);
        return 0;
    }
    virtual int remove(IFile *ifile) override
    {
        m_list->remove(ifile);
        return 0;
    }
    virtual std::list<IFile *> * getChild() override
    {
        return m_list;
    }
private:
    std::list<IFile *> * m_list;
    std::string m_name;
};

void showTree(IFile *ifile, int level)
{
    std::list<IFile *> *l = nullptr;
    for (int i = 0; i < level; i++)
    {
        std::cout << ">|	";
    }
    ifile->display();

    l = ifile->getChild();
    if (l != nullptr)
    {
        for (std::list<IFile *>::iterator it=l->begin(); it!=l->end(); it++)
        {
            if ((*it)->getChild() == nullptr)
            {
                for (int i = 0; i <= level; i++)
                {
                    std::cout << ">|	";
                }
                (*it)->display();
            }
            else
            {
                showTree((*it), level+1);
            }
        }
    }
}

void mytest()
{
    Folder *root = new Folder("C:");
    Folder *dir1 = new Folder("111dir");
    File *txt1 = new File("aaa.txt");
    Folder *dir2 = new Folder("222dir");
    File *txt2 = new File("bbb.txt");

    // 注意: 这里实参是形参的子类, 因为父类(形参)指针或引用可以指向子类对象(实参)
    // 参数类型的逆变(contravariance)是指实现的参数类型是接口或委托定义的参数类型的父类。
    // 返回类型的协变(covariance)指返回类型是接口或委托定义返回类型的子类。
    root->add(dir1);
    root->add(txt1);
    dir1->add(dir2);
    dir1->add(txt2);
    /* 添加后的布局
    Folder m_name: C:
    >|      Folder m_name: 111dir
    >|      >|      Folder m_name: 222dir
    >|      >|      File m_name: bbb.txt
    >|      File m_name: aaa.txt
    */

    /* 打印单个目录下面的文件和目录
    std::list<IFile *> * l= dir1->getChild();
    for (std::list<IFile *>::iterator it=l->begin(); it!=l->end(); it++)
    {
        (*it)->display();
    }
    */
    std::cout << "测试递归函数" << std::endl;
    showTree(root, 0);

    delete txt2;
    txt2 = nullptr;
    delete dir2;
    dir2 = nullptr;
    delete txt1;
    txt1 = nullptr;
    delete dir1;
    dir1 = nullptr;
    delete root;

    return;
}


int main()
{
    mytest();

    system("pause");
    return 0;
}
原文地址:https://www.cnblogs.com/lsgxeva/p/7778357.html