Composite组合模式 “数据结构”模式
- 常常有一些组件在内部具有特定的数据结构,如果让客户程序依赖这些特定的数据结构,将极大地破坏组件地复用。这时候,将这些特定数据结构封装在内部,在外部提供统一地接口,来实现特定数据结构无关地访问,是一种行之有效地解决方案。
- 典型模式
- Composite
- Iterator
- Chain of Resposibility
- 软件在某些情况下,客户代码过多地依赖于对象容器复杂地内部实现结构,对象容器内部实现结构(而非抽象接口)地变化将引起客户代码地频繁变化,带来了代码地维护性、扩展性等弊端。
- 如何将“客户代码与复杂地对象容器结构”解耦?让独享容器自己来实现自身地复杂结构,从而使得客户代码就像处理简单对象一样来处理复杂的对象容器。
结构(Structure)
文章图片
要点总结
- Composite模式采用树形结构来实现普遍存在的对象容器,从而将“一对多”的关系转化为“一对一”的关系,使得客户代码可以一致地(复用)处理对象和对象容器,无需关心处理地是单个的对象,还是组合的对象容器。
- 将“客户代码与复杂的对象容器结构”解耦是Composite的核心思想,解耦之后,客户代码将与存粹的抽象接口——而非独享容器的内部实现结构——发生依赖,从而更能“应对变化”。
- Composite模式在具体实现中,可以让父对象中的子对象反向追溯;如果父对象有频繁的遍历需求,可使用缓存技巧来改善效率。
#include
#include
#include
#include using namespace std;
class Component
{
public:
virtual void process() = 0;
virtual ~Component(){}
};
//树节点
class Composite : public Component{string name;
list elements;
public:
Composite(const string & s) : name(s) {}void add(Component* element) {
elements.push_back(element);
}
void remove(Component* element){
elements.remove(element);
}void process(){//1. process current node//2. process leaf nodes
for (auto &e : elements)
e->process();
//多态调用}
};
//叶子节点
class Leaf : public Component{
string name;
public:
Leaf(string s) : name(s) {}void process(){
//process current node
}
};
void Invoke(Component & c){
//...
c.process();
//...
}int main()
{Composite root("root");
Composite treeNode1("treeNode1");
Composite treeNode2("treeNode2");
Composite treeNode3("treeNode3");
Composite treeNode4("treeNode4");
Leaf leat1("left1");
Leaf leat2("left2");
root.add(&treeNode1);
treeNode1.add(&treeNode2);
treeNode2.add(&leaf1);
root.add(&treeNode3);
treeNode3.add(&treeNode4);
treeNode4.add(&leaf2);
process(root);
process(leaf2);
process(treeNode3);
}
推荐阅读
- 面试|我经历的IT公司面试及离职感受(转)
- 个人日记|K8s中Pod生命周期和重启策略
- java|设计模式——创建型——工厂方法(Factory Method)
- 设计模式|设计模式_创建型模式——工厂方法
- 设计模式|设计模式——创建型软件设计模式——工厂方法模式
- 学习分享|【C语言函数基础】
- C++|C++浇水装置问题
- 数据结构|C++技巧(用class类实现链表)
- C++|从零开始学C++之基本知识
- 步履拾级杂记|VS2019的各种使用问题及解决方法