组合模式(Composite Pattern)-结构型
意图:组合模式,将对象组合成树形结构以表示“部分-整体”的层次结构,组合模式使得用户对单个对象和组合对象的使用具有一致性。
举例:组合模式让你可以优化处理递归或分级数据结构。有许多关于分级数据结构的例子,使得组合模式非常有用武之地。
例如计算机的文件系统,文件系统由目录和文件组成。每个目录下可以有文件或是目录。目录的内容可以是文件,也可以是目录。
按照这种方式,计算机的文件系统就是以递归结构来组织的。如果你想要描述这样的数据结构,那么你可以使用组合模式Composite。
涉及角色:
1.Component 是组合中的对象声明接口,在适当的情况下,实现所有类共有接口的默认行为。声明一个接口用于访问和管理Component子部件。
2.Leaf 在组合中表示叶子结点对象,叶子结点没有子结点。
3.Composite 定义有枝节点行为,用来存储子部件,在Component接口中实现与子部件有关操作,如增加(add)和删除(remove)等。
适用性场景:
1.你想表示对象的部分-整体层次结构
2.你希望用户忽略组合对象与单个对象的不同,用户将统一地使用组合结构中的所有对象。
组合模式的结构图:
兑现代码:
#include <iostream>
#include <string>
#include "list"
using namespace std;
class IFile
{
public:
virtual void display()=0;
virtual int add(IFile *ifile)=0;
virtual int remove(IFile *ifile)=0;
virtual list<IFile*>* getChild()=0;
};
class File :public IFile
{
public:
File(string name)
{
m_name=name;
}
virtual void display()
{
cout<< m_name<<endl;
}
virtual int add(IFile *ifile)
{
return -1;
}
virtual int remove(IFile *ifile)
{
return -1;
}
virtual list<IFile*>* getChild()
{
return NULL;
}
private:
string m_name;
};
//目录节点
class Dir :public IFile
{
public:
Dir(string name)
{
m_name=name;
m_list = new list<IFile*>;
}
virtual void display()
{
cout<< m_name<<endl;
}
virtual int add(IFile *ifile)
{
m_list->push_back(ifile);
return 0;
}
virtual int remove(IFile *ifile)
{
m_list->remove(ifile);
return 0;
}
virtual list<IFile*> * getChild()
{
return m_list;
}
private:
string m_name;
list<IFile*> *m_list;
};
void showTree(IFile*root,int level)
{
//递归的显示
if(root==NULL)
{
return ;
}
int i=0;
for(i=0;i<level;i++)
{
printf("\t");
}
root->display();
list<IFile*> *list1 = root->getChild();
if(list1!=NULL)//C盘下有东西可能是文件也可能是目录,可能都有
{
for(list<IFile*>::iterator it = list1->begin();it!=list1->end();it++)
{
if((*it)->getChild()==NULL)//说明是文件
{
for(i=0;i<=level;i++)
{
printf("\t");
}
(*it)->display();
}
else//说明是目录
{
showTree(*it,level+1);
}
}
}
}
void main()
{
Dir *root = new Dir("C:");
Dir *dir1 = new Dir("dir1");
Dir *dir2 = new Dir("dir2");
File *file1 = new File("file1");
File *file2 = new File("file2");
//往目录c盘下添加文件和目录
root->add(dir1);
root->add(file1);
dir1->add(file2);
dir1->add(dir2);
//root->display();
//获取root下的集合
list<IFile*> *list1 = root->getChild();
showTree(root,0);
cout<<"nihao..."<<endl;
system("pause");
return ;
}
运行结果: