zoukankan      html  css  js  c++  java
  • 结构模式->组合模式

           组合模式(Composite Pattern):组合多个对象形成树形结构以表示具有“整体—部分”关系的层次结构。组合模式对单个对象(即叶子对象)和组合对象(即容

    器对象)的使用具有一致性,组合模式又可以称为“整体—部分”(Part-Whole)模式,它是一种对象结构型模式。

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

    注意两个字“树形”。这种树形结构在现实生活中随处可见,比如一个集团公司,它有一个母公司,下设很多家子公司。不管是母公司还是子公司,都有各自直属的财务部、人力资源部、销售部等。对于母公司来说,不论是子公司,还是直属的财务部、人力资源部,都是它的部门。整个公司的部门拓扑图就是一个树形结构。

          下面给出组合模式的UML图。从图中可以看到,FinanceDepartment、HRDepartment两个类作为叶结点,因此没有定义添加函数。而ConcreteCompany类可以作为中间结点,所以可以有添加函数。那么怎么添加呢?这个类中定义了一个链表,用来放添加的元素。

           相应的代码实现为:

    class Company    
    {  
    public:  
        Company(string name) { m_name = name; }  
        virtual ~Company(){}  
        virtual void Add(Company *pCom){}  
        virtual void Show(int depth) {}  
    protected:  
        string m_name;  
    };  
    //具体公司  
    class ConcreteCompany : public Company    
    {  
    public:  
        ConcreteCompany(string name): Company(name) {}  
        virtual ~ConcreteCompany() {}  
        void Add(Company *pCom) { m_listCompany.push_back(pCom); } //位于树的中间,可以增加子树  
        void Show(int depth)  
        {  
            for(int i = 0;i < depth; i++)  
                cout<<"-";  
            cout<<m_name<<endl;  
            list<Company *>::iterator iter=m_listCompany.begin();  
            for(; iter != m_listCompany.end(); iter++) //显示下层结点  
                (*iter)->Show(depth + 2);  
        }  
    private:  
        list<Company *> m_listCompany;  
    };  
    //具体的部门,财务部  
    class FinanceDepartment : public Company   
    {  
    public:  
        FinanceDepartment(string name):Company(name){}  
        virtual ~FinanceDepartment() {}  
        virtual void Show(int depth) //只需显示,无限添加函数,因为已是叶结点  
        {  
            for(int i = 0; i < depth; i++)  
                cout<<"-";  
            cout<<m_name<<endl;  
        }  
    };  
    //具体的部门,人力资源部  
    class HRDepartment :public Company    
    {  
    public:  
        HRDepartment(string name):Company(name){}  
        virtual ~HRDepartment() {}  
        virtual void Show(int depth) //只需显示,无限添加函数,因为已是叶结点  
        {  
            for(int i = 0; i < depth; i++)  
                cout<<"-";  
            cout<<m_name<<endl;  
        }  
    };  
    
    客户使用方式:
    int main()  
    {  
        Company *root = new ConcreteCompany("总公司");  
        Company *leaf1=new FinanceDepartment("财务部");  
        Company *leaf2=new HRDepartment("人力资源部");  
        root->Add(leaf1);  
        root->Add(leaf2);  
      
        //分公司A  
        Company *mid1 = new ConcreteCompany("分公司A");  
        Company *leaf3=new FinanceDepartment("财务部");  
        Company *leaf4=new HRDepartment("人力资源部");  
        mid1->Add(leaf3);  
        mid1->Add(leaf4);  
        root->Add(mid1);  
        //分公司B  
        Company *mid2=new ConcreteCompany("分公司B");  
        FinanceDepartment *leaf5=new FinanceDepartment("财务部");  
        HRDepartment *leaf6=new HRDepartment("人力资源部");  
        mid2->Add(leaf5);  
        mid2->Add(leaf6);  
        root->Add(mid2);  
        root->Show(0);  
      
        delete leaf1; delete leaf2;  
        delete leaf3; delete leaf4;  
        delete leaf5; delete leaf6;   
        delete mid1; delete mid2;  
        delete root;  
        return 0;  
    }  
        上面的实现方式有缺点,就是内存的释放不好,需要客户自己动手,非常不方便。有待改进,比较好的做法是让ConcreteCompany类来释放。因为所有的指针都是存在ConcreteCompany类的链表中。C++的麻烦,没有垃圾回收机制。

    其实组合模式类似与 数据结构中的树形式 存储  以前我们做的是简单的有序二叉树 存储仅仅是int  其实可以将int 抽象化为一个对象 放置对象 也可以。
         透明方式 跟 安全方式   

    关注公众号 海量干货等你
  • 相关阅读:
    django控制台输出sql日志
    Find概述
    命令大全
    京东智联云在 Serverless 的探索
    如何优雅地部署一个 Serverless Next.js 应用
    腾讯云 Serverless 保障《创造营》硬糖少女 C 位出道
    Serverless 应用实践及典型案例解析
    LeetCode 数组:62. 不同路径(动态规划 带记忆的递归)
    LeetCode 数组:56.合并区间(数组的自带排序函数 区间合并问题)
    LeetCode 数组:162. 寻找峰值(二分法)
  • 原文地址:https://www.cnblogs.com/sowhat1412/p/12734428.html
Copyright © 2011-2022 走看看