Composite模式
意图:将对象组合成树形结构表示“部分-整体”的层次结构。Composite使得用户对单个对象和组合对象的使用具有一致性。
动机: 软件在某些情况下,客户代码过多的依赖于对象容器复杂的内部实现结构,对象容器内部结构(而非抽象接口)的变换将引起客户代码的频繁变化,带来了代码的维护性,扩展性等弊端。
适用性:
1. 你想表示对象的部分-整体层次结构
2. 你希望用户忽略组合对象与单个对象的不同,用户将统一地使用组合结构中所有的对象。
结构:
参与者:
Component:为组合中的对象声明接口;在适当的情况下,实现所有类共有接口的缺省行为;声明一个接口用户访问和管理Component的子组件;在递归结构中定义一个接口,用于访问一个父部件,并在合适的情况下实现它。
Leaf: 在组合中表示叶结点对象,叶结点没有子结点;在组合中定义对象的行为。
Composite: 定义有子部件的那些部件的行为;存储子部件;在Component接口中实现与子部件有关的操作。
Client:通过component接口操纵组合部件对象
协作:
用户使用Component类接口与组合结构中的对象进行交互,如果接受者是叶结点,则直接处理请求;如果接受者是Composite,它通常将请求转发给它的子部件。
效果:
1. 定义了包含基本对象和组合对象的类层次结构
2. 简化客户代码
3. 使得更容易增加新类型的组件
4. 使设计更加一般化
实现:
代码示例如下:
#include <iostream>
#include <vector>
#include <string>
#include <algorithm>
class Component{
public:
virtual ~Component(){}
virtual void Process() = 0;
virtual void Add(Component *){}
virtual void Remove(Component *){}
Component *getChild(int){ return nullptr;}
protected:
Component(){}
Component(const std::string& name): _name(name){}
std::string _name;
};
class Composite : public Component{
public:
Composite(){}
Composite(const std::string& name):Component(name){}
~Composite(){}
void Process(){
std::cout << "name : " << _name << std::endl;
for (auto c : _component) {
c->Process();
}
}
void Add(Component *c){
_component.emplace_back(c);
}
void Remove(Component *c){
auto it = std::find(_component.begin(),_component.end(),c);
if (it != _component.end()){
Component *temp = *it;
_component.erase(it);
delete temp;
temp = nullptr;
}
}
Component *getChild(int index){
if (index < 0 || index > _component.size()){
return nullptr;
}
return _component[index];
}
private:
std::vector<Component *> _component;
};
class Leaf : public Component{
public:
Leaf(){}
Leaf(std::string const& name) :Component(name){}
~Leaf(){}
void Process(){
std::cout << "I am " << _name << std::endl;
}
};
int main(int argc,char *argv[])
{
Composite* root = new Composite("root");
Composite* leftTree = new Composite("left tree");
Composite* rightTree = new Composite("right tree");
Leaf *leaf1 = new Leaf("left leaf 1");
Leaf *leaf2 = new Leaf("right leaf 2");
Leaf *leaf3 = new Leaf("left leaf 3");
Leaf *leaf4 = new Leaf("right leaf 4");
leftTree->Add(leaf1);
leftTree->Add(leaf2);
rightTree->Add(leaf3);
rightTree->Add(leaf4);
root->Add(leftTree);
root->Add(rightTree);
root->Process();
leftTree->Remove(leaf1);
leftTree->Remove(leaf2);
rightTree->Remove(leaf3);
rightTree->Remove(leaf4);
root->Remove(rightTree);
root->Remove(leftTree);
delete root;
return 0;
}
发布于 2020-11-26 15:17