C++设计模式之组合模式
组合模式,将对象组合成树形结构以表示“部分-整体”的层次结构,组合模式使得用户对单个对象和组合对象的使用具有一致性。
一、缘由
在自然界中常常存在着许多树形关系,例如公司的结构,有子公司,部门。又如文件系统的结构,目录下边有目录或者文件,而目录下的目录又有目录和文件,如此递归下去。而组合模式就是为了处理这种树形关系而存在的。
二、实现
组合模式 天生就是为了表达树形关系的,树形关系的定义是递归的,故而组合模式的定义显然也是递归的。组合模式的UML类图如下:
在组合模式中存在三个角色:
Component 抽象构件类。该类给用户提供了一个统一的视角,用户可以对叶子和容器进行编程而无需在乎是叶子类或者是容器类。
Composite,容器构件类。容器构件类一方面可以提供操作如叶子类一样,另一方面有可以包含子构件,子构建可以是容易构件也可以是叶子类。如果用文件系统来类比,容易构件类就是目录。
Leaf,叶子类。叶子类可以提供功能操作,但是无法容纳子构件。如果用文件系统来类比,叶子节点就是普通文件。
三、实例代码
#include <string>
#include <iostream>
#include <vector>
#include <algorithm>
using std::string;
class Component {
public:
virtual ~Component (){};
virtual void operation() = 0;
virtual void add(Component *subComponent){}
virtual void remove(Component *subComponent){}
virtual Component *getChild(std::vector<Component*>::size_type index){
return NULL;
}
};
class Leaf : public Component{
public:
virtual ~Leaf(){};
virtual void operation() override{
std::cout << "Here is leaf" << std::endl;
}
};
class Composite : public Component {
private:
std::vector<Component*> children;
public:
virtual ~Composite (){
for(auto &child : children)
delete child;
};
virtual void operation() override{
std::cout << "Here is composite. childen : " << std::endl;
for (auto &child : children){
child->operation();
}
};
virtual void add(Component *subComponent) override{
children.push_back(subComponent);
}
virtual void remove(Component *subComponent) override{
auto ret = std::find(children.begin(), children.end(),
subComponent);
if (ret == children.end())
return;
children.erase(ret);
}
virtual Component *getChild(std::vector<Component*>::size_type index) override{
if (index > children.size())
return nullptr;
return children[index];
}
};
int main(void)
{
Component *component = new Composite;
component->add(new Composite);
component->add(new Composite);
component->add(new Leaf);
component->add(new Leaf);
component->getChild(1)->add(new Leaf);
component->getChild(1)->add(new Leaf);
component->getChild(1)->add(new Leaf);
component->operation();
}
运行结果:
Here is composite. childen :
Here is composite. childen :
Here is composite. childen :
Here is leaf
Here is leaf
Here is leaf
Here is leaf
Here is leaf