欢迎您访问程序员文章站本站旨在为大家提供分享程序员计算机编程知识!
您现在的位置是: 首页

组合模式

程序员文章站 2022-06-03 08:33:12
...

定义:

将对象以树形结构组织起来,以达成部分-整体的层次结构,使得客户端对单个对象和组合对象的使用具有一致性。

UML图:

组合模式

在Component中声明所有用来管理子对象的方法,其中包括Add、Remove等,这样实现Component接口的所有子类都具备了Add和Remove。这样做的好处就是叶节点和枝节点对于外界没有区别,它们具备 完全一致的行为 接口。但问题也很明显,因为Leaf类本身不具备Add()、Remove()方法的 功能,所以实现它是没有意义的。

 1.Component 是组合中的对象声明接口,在适当的情况下,实现所有类共有接口的默认行为。声明一个接口用于访问和管理Component子部件。

 2.Leaf 在组合中表示叶子结点对象,叶子结点没有子结点。

 3.Composite 定义有枝节点行为,用来存储子部件,在Component接口中实现与子部件有关操作,如增加(add)和删除(remove)等。

使用环境:

在设计中想表示对象的部分整体层次结构;

希望用户忽略组合对象与单个对象的不同,统一地使用组合结构中的所有对象。

安全性与透明性:

组合模式中必须提供对子对象的管理方法,不然无法完成对子对象的添加删除等等操作,也就失去了灵活性和扩展性。但是管理方法是在Component中就声明还是在Composite中声明呢?

一种方式是在Component里面声明所有的用来管理子类对象的方法,以达到Component接口的最大化,这样继承Component的子类都具备了。好处是使客户看来在接口层次上树叶和分支没有区别,它们具备完全一致的行为接口——透明性。但树叶是不存在子类的,因此Component声明的一些方法对于树叶来说是不适用的,实现那些方法是没意义的。这样也就带来了一些安全性问题。

  另一种方式就是只在Composite里面声明所有的用来管理子类对象的方法。这样叶子子类就不需要实现那些方法。这样就避免了上一种方式的安全性问题,但是由于叶子和分支有不同的接口,所以又失去了透明性,客户端的调用需要做相应的判断,带来了不便。

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

using namespace std;

class Company//Component
{
public:
    Company(char* name):mName(name){}
    virtual void attach(Company* cpn){}
    virtual void detach(Company* cpn){}
    virtual void display(string str){}

    virtual void LineOfDuty(string company){}

protected:
    char* mName;
    list<Company* > mList;
};

class ConcreteCompany:public Company{//Composite
public:
    ConcreteCompany(char* name):Company(name){}
    virtual void attach(Company* cpn)
    {
        if(NULL != cpn)
        {
            mList.push_back(cpn);
        }
    }
    virtual void detach(Company* cpn)
    {
        if(NULL != cpn)
        {
            mList.remove(cpn);
        }
    }
    virtual void display(string str)
    {
        list<Company* >::iterator beg = mList.begin();
        cout<<str<<mName<<endl;
        str = str + str;
        for ( ; beg != mList.end(); beg++)
        {
            (*beg)->display(str);
        }
    }
    virtual void LineOfDuty(string company)
    {
        list<Company* >::iterator beg = mList.begin();
        string name = mName;
        for ( ; beg != mList.end(); beg++)
        {
            (*beg)->LineOfDuty(name);
        }
    }
};

class HrDepartment:public Company{//Leaf
public:
    HrDepartment(char* name):Company(name){}
    virtual void display(string str)
    {
        cout<<str<<mName<<endl;
    }
    virtual void LineOfDuty(string company)
    {
        cout<<company<<"员工招聘培训管理!"<<endl;
    }
};

class FinanceDepartment:public Company{//Leaf
public:
    FinanceDepartment(char* name):Company(name){}
    virtual void display(string str)
    {
        cout<<str<<mName<<endl;
    }

    virtual void LineOfDuty(string company)
    {
        cout<<company<<"公司财务收支管理!"<<endl;
    }
};

int main()//客户端
{
    ConcreteCompany com1("木鸟飞公司");
    FinanceDepartment com2("总公司财务部");
    HrDepartment com3("总公司人力部");

    com1.attach(&com2);
    com1.attach(&com3);

    ConcreteCompany com11("木鸟飞东北分公司");
    FinanceDepartment com22("东北分公司财务部");
    HrDepartment com33("东北分公司人力部");

    com11.attach(&com22);
    com11.attach(&com33);

    com1.attach(&com11);

    string str("─");
    com1.display(str);

    cout<<endl;

    com1.LineOfDuty(str);
    return 0;
}
组合模式
相关标签: 组合模式