• 结构型模式 组合模式


    结构型模式 组合模式

    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;
    }
  • 相关阅读:
    后缀数组---Milk Patterns
    后缀数组---New Distinct Substrings
    《程序员代码面试指南》第二章 链表问题 单链表的排序
    《程序员代码面试指南》第二章 链表问题 两个单链表相交的一系列问题
    《程序员代码面试指南》第二章 链表问题 按照左右半区的方式重新组合成新链表
    《程序员代码面试指南》第二章 链表问题 合并两个有序的单链表
    《程序员代码面试指南》第二章 链表问题 向有序环形单链表中插入新节点
    《程序员代码面试指南》第二章 链表问题 搜索二叉树转换为双向链表
    《程序员代码面试指南》第二章 链表问题 在单链表中删除指定值的节点
    《程序员代码面试指南》第二章 链表问题 删除无序链表中值重复的链表
  • 原文地址:https://www.cnblogs.com/lsgxeva/p/7778357.html
Copyright © 2020-2023  润新知