您的位置:首页 > 其它

大话设计模式学习(十四)——组合模式

2010-11-21 16:57 393 查看
组合模式(Composite),将对象组合成树形结构以表示‘部分-整体’的层次结构。组合模式使得用户对单个对象和组合对象的使用具有一致性



Component为组合中的对象声明接口,在适当情况下,实现所有类共有接口的默认行为。声明一个接口用于访问和管理Component的子部件
class Component {
public:
Component(CString name)
{
strName=name;
}
CString strName;
//添加树叶的接口
virtual void Add(Component* c)=0;
//移除树叶的接口
virtual void Remove(Component* c)=0;
virtual void Display(int depth)=0;
};


Leaf在组合中表示叶节点,叶节点没有子节点
class Leaf : public Component {
public:
Leaf(CString name):Component(name){};

/*
*	由于叶子没有再增加分支和树叶,所以Add和Remove方法实现它没有意义
*  但是这样做可以消除叶节点和枝节点对象在抽象层次的区别,他们具备完全一致的接口
*/
void Add(Component* c)
{
cout<<_T("Cannot add to a leaf")<<endl;
}
void Remove(Component* c)
{
cout<<_T("Cannot remove from a leaf")<<endl;
}
/*
*	显示名称和级别
*/
void Display(int depth)
{
CString strOutput=CString('-',depth);
strOutput.Format(_T("%s %s"),strOutput,strName);
cout<<strOutput<<endl;
}
};


Composite 定义有枝节点行为,用来存储子部件,在Component接口中实现与子部件有关的操作,比如增加Add和删除Remove
#include "Component.h"
#include <vector>
using namespace std;
class Composite : public Component {
public:
Composite(CString name):Component(name)
{

}
~Composite()
{
for(vector<Component*>::iterator iter=children.begin();iter!=children.end();iter++)
{
Component* curComponent=(Component*)*iter;
delete curComponent;
curComponent=NULL;
}
children.clear();
}
void Add(Component* c)
{
children.push_back(c);
}
void Remove(Component* c)
{
for(vector<Component*>::iterator iter=children.begin();iter!=children.end();iter++)
{
Component* curComponent=(Component*)*iter;
if (curComponent==c)
{
delete curComponent;
curComponent=NULL;
children.erase(iter);
break;
}
}
}
/*
*	显示其枝节点名称,并对其下级进行遍历
*/
void Display(int depth)
{
CString strOutput=CString('-',depth);
strOutput.Format(_T("%s %s"),strOutput,strName);
cout<<strOutput<<endl;
for(vector<Component*>::iterator iter=children.begin();iter!=children.end();iter++)
{
Component* curComponent=(Component*)*iter;
curComponent->Display(depth+2);
}
}

private:
//一个子对象集合用来存储其下属的枝节点和叶节点
vector<Component*> children;
};


客户端代码,能通过Component接口操作组合部件的对象
void main()
{
//生成树根root,根上长出两叶Leaf a和Leaf b
Composite* root = new Composite("root");
root->Add(new Leaf("Leaf a"));
root->Add(new Leaf("Leaf b"));

Composite* comp = new Composite("composite x");
comp->Add(new Leaf("Leaf xa"));
comp->Add(new Leaf("Leaf xb"));

root->Add(comp);

Composite* comp2=new Composite("Composite XY");
comp2->Add(new Leaf("Leaf XYA"));
comp2->Add(new Leaf("Leaf XYB"));
comp->Add(comp2);

root ->Add(new Leaf("Leaf c"));

Leaf* leaf=new Leaf("Leaf d");
root->Add(leaf);
root->Remove(leaf);
//显示
root->Display(1);

}


结果显示:
- root
--- Leaf a
--- Leaf b
--- composite x
----- Leaf xa
----- Leaf xb
----- Composite XY
------- Leaf XYA
------- Leaf XYB
--- Leaf c
当你发现需求中是体现部分与整体层次的结构时,以及你希望用户可以忽略组合对象与单个对象的不同,统一地使用组合结构中的所有对象时,就应该考虑使用组合模式了
内容来自用户分享和网络整理,不保证内容的准确性,如有侵权内容,可联系管理员处理 点击这里给我发消息
标签: