设计模式之组合模式

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类里面声明所有的用来管理子类对象的方法。这样的做法是安全的做法,因为树叶类型的对象根本就没有管理子类对象的方法,因此,如果客户端对树叶类对象使用这些方法时,程序会在编译时期出错。

这个选择的缺点是不够透明,因为树叶类和合成类将具有不同的接口。



  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值