• 组合模式(C++)


    介绍

    组合模式: 又叫部分整体模式,是用于把一组相似对象当做一个单一对象.组合模式依据树形结构来组合对象,用来表示部分以及整体层次. 属于结构型模式.

    目的: 将对象组合成树形结构以表示"部分-整体"的层次关.组合模式使得用户对单个对象和组合对象的使用具有一致性.

    优点:

    • 高层模块调用简单;
    • 自由度高.

    缺点:

    • 叶子和树枝的声明都是实现类,违反了依赖倒置原则.

    使用场景:

    • 想表达对象的部分-整体层次关系时;
    • 希望忽略单个对象和组合对象的不同, 客户端将统一的使用组合结构中的所有对象.

    UML

    image

    示例

    本示例copy自: https://www.cnblogs.com/chengjundu/p/8473564.html

    /*
    * 关键代码:树枝内部组合该接口,并且含有内部属性list,里面放Component。
    */
    
    #include <iostream>
    #include <list>
    #include <memory>
    
    using namespace std;
    
    //抽象类,提供组合和单个对象的一致接口
    class Company
    {
    public:
        Company(const string& name): m_name(name){}
        virtual ~Company(){ cout << "~Company()" << endl;}
    
        virtual void add(Company* ) = 0;
        virtual void remove(const string&) = 0;
        virtual void display(int depth) = 0;
    
        virtual const string& name()
        {
            return m_name;
        }
    
    protected:
        string m_name;
    };
    
    //具体的单个对象实现类,“树枝”类
    class HeadCompany : public Company
    {
    public:
        HeadCompany(const string& name): Company(name){}
        virtual ~HeadCompany(){ cout << "~HeadCompany()" << endl;}
    
        void add(Company* company) override
        {
            shared_ptr<Company> temp(company);
            m_companyList.push_back(temp);
        }
    
        void remove(const string& strName) override
        {
            list<shared_ptr<Company>>::iterator iter = m_companyList.begin();
            for(; iter != m_companyList.end(); iter++)
            {
                if((*iter).get()->name() == strName)
                {
                //不应该在此处使用list<T>.erase(list<T>::iterator iter),会导致iter++错误,这里删除目               标元素之后,必须return。
                    m_companyList.erase(iter);
                    return;
                }
            }
        }
    
        void display(int depth) override
        {
            for(int i = 0; i < depth; i++)
            {
                cout << "-";
            }
            cout << this->name().data() << endl;
            list<shared_ptr<Company>>::iterator iter = m_companyList.begin();
            for(; iter!= m_companyList.end(); iter++)
            {
                (*iter).get()->display(depth + 1);
            }
        }
    
    private:
        list<shared_ptr<Company>> m_companyList;
    };
    
    //具体的单个对象实现类,“树叶”类
    class ResearchCompany : public Company
    {
    public:
        ResearchCompany(const string& name): Company(name){}
        virtual ~ResearchCompany(){ cout << "~ResearchCompany()" << endl;}
    
        void add(Company* ) override
        {
        }
    
        void remove(const string&) override
        {
        }
    
        void display(int depth) override
        {
            for(int i = 0; i < depth; i++)
            {
                cout << "-";
            }
            cout << m_name.data() << endl;
        }
    };
    
    //具体的单个对象实现类,“树叶”类
    class SalesCompany : public Company
    {
    public:
        SalesCompany(const string& name): Company(name){}
        virtual ~SalesCompany(){ cout << "~SalesCompany()" << endl;}
    
        void add(Company* ) override
        {
        }
    
        void remove(const string&) override
        {
        }
    
        void display(int depth) override
        {
            for(int i = 0; i < depth; i++)
            {
                cout << "-";
            }
            cout << m_name.data() << endl;
        }
    };
    
    //具体的单个对象实现类,“树叶”类
    class FinanceCompany : public Company
    {
    public:
        FinanceCompany(const string& name): Company(name){}
        virtual ~FinanceCompany(){ cout << "~FinanceCompany()" << endl;}
    
        void add(Company* ) override
        {
        }
    
        void remove(const string&) override
        {
        }
    
        void display(int depth) override
        {
            for(int i = 0; i < depth; i++)
            {
                cout << "-";
            }
            cout << m_name.data() << endl;
        }
    };
    
    
    int main()
    {
        HeadCompany* headRoot = new HeadCompany("Head Root Company");
    
        HeadCompany* childRoot1 = new HeadCompany("Child Company A");
        ResearchCompany* r1 = new ResearchCompany("Research Company A");
        SalesCompany* s1 = new SalesCompany("Sales Company A");
        SalesCompany* s2 = new SalesCompany("Sales Company B");
        FinanceCompany* f1 = new FinanceCompany("FinanceCompany A");
    
        childRoot1->add(r1);
        childRoot1->add(s1);
        childRoot1->add(s2);
        childRoot1->add(f1);
    
        HeadCompany* childRoot2 = new HeadCompany("Child Company B");
        ResearchCompany* r2 = new ResearchCompany("Research Company B");
        SalesCompany* s3 = new SalesCompany("Sales Company C");
        SalesCompany* s4 = new SalesCompany("Sales Company D");
        FinanceCompany* f2 = new FinanceCompany("FinanceCompany B");
    
        childRoot2->add(r2);
        childRoot2->add(s3);
        childRoot2->add(s4);
        childRoot2->add(f2);
    
        headRoot->add(childRoot1);
        headRoot->add(childRoot2);
        headRoot->display(1);
    
        cout << "
    ***************
    " << endl;
    
        childRoot1->remove("Sales Company B");
        headRoot->display(1);
    
        cout << "
    ***************
    " << endl;
    
        delete headRoot;
        headRoot = nullptr;
    
        return 0;
    }
    
  • 相关阅读:
    CTeX里面CTRL-Space和中文输入法的冲突问题解决
    用LaTeX画树形结构
    统计学howto
    Lights Out Game
    ubuntu下安装 Source insight
    github常用命令
    编程珠玑:第7章(初略估算)的阅读体会
    在windows上安装common lisp开发环境
    睡眠十律:程序员必看
    网络和服务器编程
  • 原文地址:https://www.cnblogs.com/xl2432/p/13151366.html
Copyright © 2020-2023  润新知