设计模式C++描述----11.组合(Composite)模式

一. 举例

这个例子是书上的,假设有一个公司的组结结构如下:


它的结构很像一棵树,其中人力资源部和财务部是没有子结点的,具体公司才有子结点。

而且最关健的是,它的每一层结构很相似。

代码实现如下:
//公司类,提供接口
class Company    
{  
public:  
    Company(string name)
    {
        m_name = name;
    }  
    
    virtual ~Company()
    {}  
    
    virtual void Add(Company *pCom)
    {}  
    
    virtual void Display(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 Display(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)->Display(depth + 2);
        }
    }

private:  
    list<Company *> m_listCompany;  
};  

//具体的部门,财务部  
class FinanceDepartment : public Company   
{
public:  
    FinanceDepartment(string name):Company(name)
    {}  
    
    virtual ~FinanceDepartment()
    {}  
    
    //只需显示,无限添加函数,因为已是叶结点  
    virtual void Display(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 Display(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);  
 
    //华东分公司
    Company *mid1 = new ConcreteCompany("华东分公司");  
    Company *leaf3=new FinanceDepartment("华东分公司财务部");  
    Company *leaf4=new HRDepartment("华东分公司人力资源部");  
    mid1->Add(leaf3);
    mid1->Add(leaf4);
    root->Add(mid1);
    
    //南京办事处
    Company *mid2=new ConcreteCompany("南京办事处");  
    FinanceDepartment *leaf5=new FinanceDepartment("南京办事处财务部");  
    HRDepartment *leaf6=new HRDepartment("南京办事处人力资源部");  
    mid2->Add(leaf5);
    mid2->Add(leaf6);
    root->Add(mid2);
 
    //杭州办事处
    Company *mid3=new ConcreteCompany("杭州办事处");  
    FinanceDepartment *leaf7=new FinanceDepartment("杭州办事处财务部");  
    HRDepartment *leaf8=new HRDepartment("杭州办事处人力资源部");  
    mid3->Add(leaf7);  
    mid3->Add(leaf8);  
    mid2->Add(mid3);

    root->Display(0);

    delete leaf1;
    delete leaf2;  
    delete leaf3;
    delete leaf4;  
    delete leaf5;
    delete leaf6;
    delete leaf7;
    delete leaf8;  
    delete mid1;
    delete mid2;  
    delete root;  
    
    return 0;
}

二. 说明

1. 上面公司的结构图其实就是整体与部分的关系,而且的话整体与部分可以一致对待,因为有很多相似之处嘛。

2. 这棵树有两种几能,要么是棵叶,要么是子棵。

其实这种模式就是组合模式。

三. 组合模式

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

要注意两点:

1. “树形”,必须是一种层次结构,有可以向下延伸的分枝,也有不变的树叶。

2. "一致性",也就是要具有很多相似性。

结构图如下:

component:主要是定义统一的接口,说白了也就是提取出相似性

composite:定义分枝节点,也就是子树。

leaf:定义叶节点,叶节点是没有子节点的。

评论 1
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值