一、 合成(Composite)模式
合成模式有时又叫做部分-整体模式(Part-Whole)。合成模式将对象组织到树结构中,可以用来描述整体与部分的关系。合成模式可以使客户端将单纯元素与复合元素同等看待。
二、 合成模式概述
下图所示的类图省略了各个角色的细节。
可以看出,上面的类图结构涉及到三个角色:
- 抽象构件(Component)角色:这是一个抽象角色,它给参与组合的对象规定一个接口。这个角色给出共有接口及其默认行为。
- 树叶构件(Leaf)角色:代表参加组合的树叶对象。一个树叶对象没有下级子对象。
- 树枝构件(Composite)角色:代表参加组合的有子对象的对象,并给出树枝构件对象的行为。
可以看出,Composite类型的对象可以包含其它Component类型的对象。换而言之,Composite类型对象可以含有其它的树枝(Composite)类型或树叶(Leaf)类型的对象。
#ifndef COMPOSITE_H_
#define COMPOSITE_H_
#include <list>
#include <string>
using namespace std;
class Component
{
public:
Component(string astrName){ m_strName = astrName; }
virtual~Component(){}
virtual void Display(int aiDepth) = 0;
protected:
string m_strName;
};
class Leaf : public Component
{
public:
Leaf(string astrName) : Component(astrName){}
virtual void Display(int aiDepth);
};
class Composite : public Component
{
public:
Composite(string astrName) :Component(astrName){}
virtual~Composite();
void Add(Component* apComponent);
void Remove(Component* apComponent);
virtual void Display(int aiDepth);
protected:
list<Component*> m_oChildren;
};
#endif
#include "stdafx.h"
#include "Composite.h"
#include <iostream>
#include <sstream>
#include <algorithm>
void Leaf::Display(int aiDepth)
{
cout<<"Leaf::Display"<<endl;
string astrDestString;
stringstream lostrStream;
lostrStream << aiDepth ;
astrDestString=lostrStream.str();
astrDestString = astrDestString + "-" +m_strName;
cout<< astrDestString<<endl;
}
void Composite::Add(Component* apComponent)
{
m_oChildren.push_back(apComponent);
}
void Composite::Remove(Component* apComponent)
{
//apComponent
//m_oChildren.find();
list<Component*>::iterator itor ;
itor = find(m_oChildren.begin(), m_oChildren.end(), apComponent);
if (itor != m_oChildren.end())
{
m_oChildren.erase(itor);
}
}
Composite::~Composite()
{
Component* lpComponent = NULL;
for (list<Component*>::iterator itor =m_oChildren.begin(); itor != m_oChildren.end(); )
{
lpComponent = *itor;
delete lpComponent;
lpComponent=NULL;
m_oChildren.erase(itor++);
}
}
void Composite::Display(int aiDepth)
{
string astrDestString;
cout<<"Composite::Display"<<endl;
stringstream lostrStream;
lostrStream << aiDepth++ ;
astrDestString=lostrStream.str();
astrDestString = astrDestString + "-" +m_strName;
cout<< astrDestString<<endl;
for (list<Component*>::iterator itor =m_oChildren.begin(); itor != m_oChildren.end(); itor++)
{
(*itor)->Display(aiDepth);
}
}
#include "stdafx.h"
#include "Composite.h"
#include <stdlib.h>
int _tmain(int argc, _TCHAR* argv[])
{
///root(深度1)----------leafa(深度2)
/// ----------leafB(深度2)
----------composite x(深度2)----------leaf Xa(深度3)
----------leaf XB(深度3)
/// ----------leaf c(深度2)
Composite *lpRoot = new Composite("root");
lpRoot->Add(new Leaf(" leaf a"));
lpRoot->Add(new Leaf(" leaf B"));
Composite* lpComposite = new Composite("composite x");
lpComposite->Add(new Leaf(" leaf Xa"));
lpComposite->Add(new Leaf(" leaf XB"));
lpRoot->Add(lpComposite);
lpRoot->Add(new Leaf("leaf c"));
Leaf *i = new Leaf("leaf d");
lpRoot->Add(i);
lpRoot->Remove(i);
lpRoot->Display(1);
system("pause");
return 0;
}