- Published on
设计模式(8)——组合 Composite
- Authors
- Name
- Leon
八、Composite(组合模式,对象结构型模式)
1. 意图:
将对象组合成树形结构以表示“部分-整体”的层次结构。Composite 使得用户对单个对象和组合对象的使用具有一致性。
2. 适用:
- 想表示对象的部分-整体层次结构
- 希望用户忽略组合对象与单个对象的不同,用户将统一地使用组合结构中的所有对象
3. 类图:
4. 相关模式:
通常部件-父部件连接用于 Responsibility of Chain 模式。 Decorator 模式经常与 Composite 模式一起使用。当装饰和组合一起使用时,它们通常有一个公共的父类。因此装饰必须支持具有 Add、Remove 和 GetChild 操作的 Component 接口。
5. C++实现:
- 编写一个组件抽象基类(接口)
Component
,含有操作函数Operation
、Add
、Remove
和GetChild
- 编写一个叶子(部分)类
Leaf
,一个组合(整体)类Composite
,都通过继承Component
而具有一致性的操作Operation
等
Composite.h
//Composite.h
#ifndef _COMPOSITE_H_
#define _COMPOSITE_H_
#include <vector>
using namespace::std;
/*
Component抽象基类,为组合中的对象声明接口,声明了类共有接口的缺省行为
如这里的Add,Remove,GetChild函数,声明一个接口函数可以访问Component的子组件
*/
class Component
{
public:
virtual void Operation() = 0;
virtual void Add(Component*);
virtual void Remove(Component*);
virtual Component* GetChild(int index);
virtual ~Component();
protected:
Component();
};
//Leaf是叶子结点,也就是不含有子组件的结点类,所以不用实现Add,Remove,GetChild等方法
class Leaf : public Component
{
public:
//只实现Operation接口
virtual void Operation();
Leaf();
~Leaf();
};
//Composite含有子组件的类
class Composite : public Component
{
public:
Composite();
~Composite();
//实现所有接口
void Operation();
void Add(Component*);
void Remove(Component*);
Component* GetChild(_Uint32t index);
private:
//这里采用vector来保存子组件
vector<Component*> m_ComVec;
};
#endif
Composite.cpp
//Composite.cpp
#include "Composite.h"
#include <iostream>
#include <algorithm>
using namespace::std;
Component::Component(){}
Component::~Component(){}
void Component::Add(Component* com)
{
cout << "add" << endl;
}
void Component::Remove(Component* com)
{
//..
}
void Component::Operation()
{
//..
cout << "Component::Operation" << endl;
}
Component* Component::GetChild(int index)
{
return NULL;
}
Leaf::Leaf(){}
Leaf::~Leaf(){}
void Leaf::Operation()
{
cout << "Leaf::Operation" << endl;
}
Composite::Composite(){}
Composite::~Composite(){}
void Composite::Add(Component* com)
{
this->m_ComVec.push_back(com);
}
void Composite::Remove(Component* com)
{
vector<Component*>::iterator iter;
iter = std::find(this->m_ComVec.begin(), m_ComVec.end(), com);
while (m_ComVec.end() != iter)
{
m_ComVec.erase(iter);
iter = std::find(m_ComVec.begin(), m_ComVec.end(), com);
}
}
void Composite::Operation()
{
cout << "Composite::Operation" << endl;
vector<Component*>::iterator iter = this->m_ComVec.begin();
for(; iter != this->m_ComVec.end(); iter++)
{
(*iter)->Operation();//递归
}
}
Component* Composite::GetChild(_Uint32t index)
{
if(index < 0 || index > this->m_ComVec.size())
{
return NULL;
}
return this->m_ComVec[index];
}
main.cpp
//main.cpp
#include "Composite.h"
#include <iostream>
using namespace::std;
int main()
{
Leaf* pLeaf1 = new Leaf();
Leaf* pLeaf2 = new Leaf();
//叶子与组合对象都继承了相同的接口,所以语法上是对的,但
//叶子Add,Remove,GetChild函数没有重新定义,都继承自基类,
//没有实际意义。
pLeaf1->Add(pLeaf2);
pLeaf1->Remove(pLeaf2);
//叶子结点实现了Opeeration()方法,
pLeaf1->Operation();
//组合对象实现了基类的所有接口,所以可以做各种操作(Add,Remove
//GetChild,Operation)。
Composite* pCom = new Composite();
//组合对象添加叶子结点
pCom->Add(pLeaf1);
pCom->Add(pLeaf2);
pCom->Operation();
Composite* pRoot = new Composite();
pRoot->Add(new Leaf());
//组合对象添加组合对象
pRoot->Add(pCom);
pRoot->Operation();
cin.get();
return 0;
}