组合模式(Composite Pattern)
常常有一些组件在内部具有特定的数据结构,如果让客户依赖这些特定的数据结构,将极大地破坏组件的复用。
这时候,将这些特定的数据结构封装在内部,在外部提供同一的接口,来实现与特定数据结构无关的访问,是一
种行之有效的解决方案。
将对象组合成树形结构以表示“ 部分-整体”的层次结构。Composite使得用户对单个对象和组合对象的使用具有
一直性(稳定) -----《设计模式》GoF
意图:
将聚合对象分解为树结构,客户对象使用同一的方式对待聚合体和组成元素
应用场景:
1. 使客户端忽略聚和体和组件的不同点,使用同一的方式来对待它们
2.客户端使用聚合对象及其组件时候,想简化客户端使用行为
影响:
1.无法限制聚合体组件的类型
类图:
** 例**
添加Component接口 :
class Componet {
public:
virtual void process() = 0;
virtual ~Componet() {}
};
Composite树结点:
class Composite : public Componet {
private:
string name;
list<Componet*> element; //可以为Comonet和Composite
public:
Composite(const string& s) : name(s) { }
//添加结点
void add(Componet* e) {
element.push_back(e);
}
void process() override {
//1.处理当前的结点
//2.处理子节点
for (auto& e : element)
e->process(); //虚函数调用(多态)
}
};
叶子结点:
class Leaf : public Componet {
private:
string name;
public:
Leaf(const string s) : name(s) {}
void process() override{
}
};
总结:
-
Composite模式采用树形结构来实现普遍存在的对象容器,从而将“一对多”的关系,
转变为“一对一”的关系,使得客户代码可以一致地(复用)处理对象和对象容器,无需
关心处理的是单个对象,还是组合的对象容器 -
Composite模式采用树形结构来实现普遍存在的对象容器,从而将“一对多”的关系,
转变为“一对一”的关系,使得客户代码可以一致地(复用)处理对象和对象容器,无需
关心处理的是单个对象,还是组合的对象容器 -
Composite模式在具体实现中 , 可以让父对象中的子类反溯;如果父对象有频繁的遍历
需求,可以使用缓存技巧来改善效率。