上一篇:http://www.BkJia.com/kf/201205/132469.html
一. 舉例
這個例子是書上的,假設有一個公司的組結結構如下:
它的結構很像一棵樹,其中人力資源部和財務部是沒有子結點的,具體公司才有子結點。
而且最關健的是,它的每一層結構很相似。
代碼實現如下:
[cpp] view plaincopyprint?//公司類,提供接口
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;
}
//公司類,提供接口
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;
};
//具體公司 www.2cto.com
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:定義葉節點,葉節點是沒有子節點的。
作者 lwbeyond