首页 > 代码库 > C++设计模式实现--组合(Composite)模式

C++设计模式实现--组合(Composite)模式

一. 举例

这个样例是书上的,如果有一个公司的组结结构例如以下:


它的结构非常像一棵树,当中人力资源部和財务部是没有子结点的,详细公司才有子结点。

并且最关健的是,它的每一层结构非常相似。

代码实现例如以下:
#include <iostream>
#include <list>
#include <string>
using namespace std;


//公司类,提供接口  
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;    
getchar();
return 0;  
}  

二. 说明

1. 上面公司的结构图事实上就是总体与部分的关系,并且的话总体与部分能够一致对待,由于有非常多相似之处嘛。

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

事实上这样的模式就是组合模式。

三. 组合模式

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

要注意两点:

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

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

结构图例如以下:

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

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

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