http://blog.csdn.net/lcl_data/article/details/8811101
http://www.cnblogs.com/jiese/p/3168844.html
组合模式
特点:用于将对象组合成树状结构,展示出“部分--整体”的层次结构。这里,单个对象和组合对象具有相同的行为接口,使得用户对单个对象和组合对象的使用具有一致性,忽略组合对象和单个对象之间的差别。
角色:
Component: 抽象基类,为组合中的对象声明接口(叶子和树枝对象),在适当情况下实现所有类共有接口的缺省行为。
Leaf: 在组合中表示叶节点子类,叶节点没有子节点,并定义其行为。
Composite: 树枝子类,拥有子部件的子类。
#include<iostream>
#include<string>
#include<list>
using namespace std;
class IFile{//Component
public:
virtual void display()=0;
virtual int add(IFile*)=0;
virtual int remove(IFile*)=0;
virtual list<IFile*>*getChild()=0;
};
class File: public IFile{//Leaf
public:
File(string nam){
name=nam;
}
void display(){
cout<<name<<endl;
};
int add(IFile* file){
return -1;
}
int remove(IFile* file){
return -1;
}
list<IFile*>*getChild(){
return 0;
}
private:
string name;
};
class Dir: public IFile{//Composite
public:
Dir(string nam){
name=nam;
m_list=new list<IFile*>;
m_list->clear();
}
void display(){
cout<<name<<endl;
};
int add(IFile* file){
m_list->push_back(file);
return 0;
}
int remove(IFile* file){
m_list->remove(file);
return 0;
}
list<IFile*>*getChild(){
if(m_list)
return m_list;
else
return 0;
}
private:
string name;
list<IFile*>* m_list;
};
void showTree(IFile* dir,int level){ //递归显示树结构
if(!dir)
return;
for(int i=0;i<level;++i)
cout<<" ";
dir->display();
list<IFile*>* child=dir->getChild();
if(child){
for(list<IFile*>::iterator pos=child->begin();pos!=child->end();++pos){
if((*pos)->getChild()==NULL){
for(int i=0;i<=level;++i)
cout<<" ";
(*pos)->display();
}
else
showTree(*pos,level+1);
}
}
}
int main(){
Dir* dir=new Dir("C");
Dir* dir1=new Dir("music");
Dir* dir2=new Dir("movie");
File* aaa=new File("panda");
File* bbb=new File("panda2");
dir->add(dir1);
dir->add(bbb);
dir1->add(dir2);
dir1->add(aaa);
dir->display();
list<IFile*>* f=dir->getChild();
for(list<IFile*>::iterator pos=f->begin();pos!=f->end();++pos)
(*pos)->display();
//显示结构树
cout<<"------------------------------------------------"<<endl;
showTree(dir,0);
return 0;
}
组合模式的实现根据所实现接口的区别分为两种形式,分别称为安全模式和透明模式。
透明模式:作为第一种选择,在Component里面声明所有的用来管理子类对象的方法,包括add()、remove(),以及getChild()方法。这样做的好处是所有的构件类都有相同的接口。在客户端看来,树叶类对象与合成类对象的区别起码在接口层次上消失了,客户端可以同等同的对待所有的对象。这就是透明形式的组合模式。
这个选择的缺点是不够安全,因为树叶类对象和合成类对象在本质上是有区别的。树叶类对象不可能有下一个层次的对象,因此add()、remove()以及getChild()方法没有意义,是在编译时期不会出错,而只会在运行时期才会出错或者说识别出来。
安全模式:第二种选择是在Composite类里面声明所有的用来管理子类对象的方法。这样的做法是安全的做法,因为树叶类型的对象根本就没有管理子类对象的方法,因此,如果客户端对树叶类对象使用这些方法时,程序会在编译时期出错。
这个选择的缺点是不够透明,因为树叶类和合成类将具有不同的接口。