理论学习:
在开发中,我们经常可能要递归构建树状的组合结构,组合模式则提供了很好的解决方案!
比如下面我写的一个程序,我们都知道重点大学可分为985重点大学和211重点大学,每所大学都有属于自己的学院,如机械工程学院、土木工程学院、人文学院等!重点大学的各学院的拓扑图就是一个树形结构。在程序中,M_University 作为中间结点,可以有添加函数(添加函数使用C++中的容器vector实现!),Ji_Xie、Tu_Mu、 Ren_Wen这些类作为叶子结点,添加函数没有意义,定义为空。在主函数中,向重点大学里面添加重点大学机械工程学院、重点大学土木工程学院、重点大学人文学院这些对象时是一一添加进去的!而向重点大学里面添加985重点大学对象和211重点大学对象时,是分别把他们作为组合对象添加进去的! 985重点大学作为一个组合对象包括985重点大学机械工程学院、985重点大学土木工程学院、985重点大学人文学院!211重点大学作为一个组合对象包括211重点大学机械工程学院、211重点大学土木工程学院、 211重点大学人文学院!
在主函数中向重点大学里面添加985重点大学这个组合对象和添加211重点大学这个组合对象,其方法和向重点大学里面添加简单的元素:重点大学机械工程学院、重点大学土木工程学院、重点大学人文学院一样,前者和后者使用的都是Add方法!这就验证了组合模式的核心思想:使得用户对单个对象和组合对象的使用具有一致性!使客户程序可以像处理简单元素一样处理复杂元素!
组合模式的C++代码实现:
在开发中,我们经常可能要递归构建树状的组合结构,组合模式则提供了很好的解决方案!
组合模式的标准定义:将对象组合成树形结构以表示“部分整体”的层次结构。组合模式使得用户对单个对象和组合对象的使用具有一致性!组合模式解耦了客户程序与复杂元素内部结构,从而使客户程序可以像处理简单元素一样处理复杂元素。(具体内涵解读请看下面的实例分析!)
比如下面我写的一个程序,我们都知道重点大学可分为985重点大学和211重点大学,每所大学都有属于自己的学院,如机械工程学院、土木工程学院、人文学院等!重点大学的各学院的拓扑图就是一个树形结构。在程序中,M_University 作为中间结点,可以有添加函数(添加函数使用C++中的容器vector实现!),Ji_Xie、Tu_Mu、 Ren_Wen这些类作为叶子结点,添加函数没有意义,定义为空。在主函数中,向重点大学里面添加重点大学机械工程学院、重点大学土木工程学院、重点大学人文学院这些对象时是一一添加进去的!而向重点大学里面添加985重点大学对象和211重点大学对象时,是分别把他们作为组合对象添加进去的! 985重点大学作为一个组合对象包括985重点大学机械工程学院、985重点大学土木工程学院、985重点大学人文学院!211重点大学作为一个组合对象包括211重点大学机械工程学院、211重点大学土木工程学院、 211重点大学人文学院!
在主函数中向重点大学里面添加985重点大学这个组合对象和添加211重点大学这个组合对象,其方法和向重点大学里面添加简单的元素:重点大学机械工程学院、重点大学土木工程学院、重点大学人文学院一样,前者和后者使用的都是Add方法!这就验证了组合模式的核心思想:使得用户对单个对象和组合对象的使用具有一致性!使客户程序可以像处理简单元素一样处理复杂元素!
组合模式的C++代码实现:
#include<iostream>
#include<string>
#include<vector>
using namespace std;
class University //抽象类,大学
{
public:
University(string name)
{
this->name = name;
}
virtual void Add(University*pUniversity) = 0; //添加函数的抽象接口
virtual void show() = 0;//显示函数的抽象接口
protected:
string name;
};
//具体类,大学(中间结点)
class M_University :public University
{
public:
M_University(string name) :University(name){}
virtual void Add(University*pUniversity)//中间结点,Add方法有意义
{
m_University.push_back(pUniversity);//往容器m_University中添加对象
}
virtual void show()//中间结点,不仅要显示本层结点还要显示本层结点的下层结点
{
cout << name << endl;//显示本层结点
vector<University*>::iterator iter = m_University.begin();//定义迭代器iter指向m_University容器中的第一个元素
for (; iter != m_University.end(); ++iter)//显示本层结点的所有下层结点
{
(*iter)->show();
}
}
private:
vector<University*> m_University; //定义一个存放University*类对象的容器m_University
};
//具体学院,机械工程学院(叶子结点)
class Ji_Xie :public University
{
public:
Ji_Xie(string name) :University(name){}
virtual void Add(University*pUniversity){}//叶子结点,Add方法没有意义,定义为空
virtual void show() //叶子结点,只需显示本层结点的内容
{
cout << name << endl;
}
};
//具体学院,土木工程学院(叶子结点)
class Tu_Mu :public University
{
public:
Tu_Mu(string name) :University(name){}
virtual void Add(University*pUniversity){}//叶子结点,Add方法没有意义,定义为空
virtual void show() //叶子结点,只需显示本层结点的内容
{
cout << name << endl;
}
};
//具体学院,人文学院(叶子结点)
class Ren_Wen :public University
{
public:
Ren_Wen(string name) :University(name){}
virtual void Add(University*pUniversity){}//叶子结点,Add方法没有意义,定义为空
virtual void show() //叶子结点,只需显示本层结点的内容
{
cout << name << endl;
}
};
int main(void)
{
University*root = new M_University("重点大学");
University*leaf1 = new Ji_Xie("重点大学的机械工程学院");
University*leaf2 = new Tu_Mu("重点大学的土木工程学院");
University*leaf3 = new Ren_Wen("重点大学的人文学院");
root->Add(leaf1);
root->Add(leaf2);
root->Add(leaf3);
University*mid1 = new M_University("985重点大学");
University*leaf4 = new Ji_Xie("985重点大学的机械工程学院");
University*leaf5 = new Tu_Mu("985重点大学的土木工程学院");
University*leaf6 = new Ren_Wen("985重点大学的人文学院");
mid1->Add(leaf4);
mid1->Add(leaf5);
mid1->Add(leaf6);
root->Add(mid1);
University*mid2 = new M_University("211重点大学");
University*leaf7 = new Ji_Xie("211重点大学的机械工程学院");
University*leaf8 = new Tu_Mu("211重点大学的土木工程学院");
University*leaf9 = new Ren_Wen("211重点大学的人文学院");
mid2->Add(leaf7);
mid2->Add(leaf8);
mid2->Add(leaf9);
root->Add(mid2);
root->show();
cout << endl;
delete root; delete mid1; delete mid2;
delete leaf1;
delete leaf2;
delete leaf3;
delete leaf4;
delete leaf5;
delete leaf6;
delete leaf7;
delete leaf8;
delete leaf9;
system("pause");
return 0;
}