结构型 - 组合(Composite)

组合模式(composite pattern): 允许你将对象组合成树形结构来表现"整体/部分"层次结构. 组合能让客户以一致的方式处理个别对象以及对象组合

概念

Composite 模式典型的结构图为:

组件(Component)类是组合类(Composite)和叶子类(Leaf)的父类,可以把组合类看成是树的中间节点。 组合对象拥有一个或者多个组件对象,因此组合对象的操作可以委托给组件对象去处理,而组件对象可以是另一个组合对象或者叶子对象。

代码实现

#ifndef _COMPONENT_H_
#define _COMPONENT_H_
class Component
{
public:
    Component();
    virtual ~Component();

public:
    virtual void Operation() = 0;
    virtual void Add(const Component &);
    virtual void Remove(const Component &);
    virtual Component *GetChild(int);

protected:
private:
};
#endif //~_COMPONENT_H_
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
#include "Component.h"

Component::Component()
{
}

Component::~Component()
{
}

void Component::Add(const Component &com)
{
}

Component *Component::GetChild(int index)
{
    return 0;
}

void Component::Remove(const Component &com)
{
}
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
#ifndef _COMPOSITE_H_
#define _COMPOSITE_H_
#include "Component.h"
#include <vector>
using namespace std;

class Composite : public Component
{
public:
    Composite();
    ~Composite();

public:
    void Operation();
    void Add(Component *com);
    void Remove(Component *com);
    Component *GetChild(int index);

protected:
private:
    vector<Component *> comVec;
};
#endif //~_COMPOSITE_H_
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
#include "Composite.h"
#include "Component.h"
#define NULL 0 // define NULL POINTOR

Composite::Composite()
{
    // vector<Component*>::iterator itend =comVec.begin();
}

Composite::~Composite()
{
}

void Composite::Operation()
{
    vector<Component *>::iterator comIter = comVec.begin();
    for (; comIter != comVec.end(); comIter++)
    {
        (*comIter)->Operation();
    }
}

void Composite::Add(Component *com)
{
    comVec.push_back(com);
}

void Composite::Remove(Component *com)
{
    //comVec.erase(&com);

    for (std::vector<Component *>::iterator iter = comVec.begin(); iter != comVec.end(); )
    {
        if (*iter == com)
        {
            iter =comVec.erase(iter);
        }
        else
        {
            iter++;
        }
    }
}

Component *Composite::GetChild(int index)
{
    return comVec[index];
}
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
#ifndef _LEAF_H_
#define _LEAF_H_
#include "Component.h"

class Leaf : public Component
{
public:
    Leaf();
    ~Leaf();
    void Operation();

protected:
private:
};

#endif //~_LEAF_H_
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
#include "Leaf.h"
#include <iostream>
using namespace std;

Leaf::Leaf()
{
}

Leaf::~Leaf()
{
}

void Leaf::Operation()
{
    cout << "Leaf operation....." << endl;
}
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
#include "Component.h"
#include "Composite.h"
#include "Leaf.h"
#include <iostream>
using namespace std;

int main(int argc, char *argv[])
{
	Leaf *l = new Leaf();
	l->Operation();
	Composite *com = new Composite();
	com->Add(l);
	com->Operation();
	Component *ll = com->GetChild(0);
	ll->Operation();
	return 0;
}
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
[root@VM-16-6-centos Composite]# ./ComponentTest
Leaf operation.....
Leaf operation.....
Leaf operation.....
1
2
3
4

代码说明

Composite 模式在实现中有一个问题就是要提供对于子节点( Leaf)的管理策略,这里使用的是 STL 中的 vector,可以提供其他的实现方式,如数组、链表、 Hash 表等。

讨论

Composite 模式通过和 Decorator 模式有着类似的结构图, 但是 Composite 模式旨在构造类,而 Decorator 模式重在不生成子类即可给对象添加职责。 Decorator 模式重在修饰, 而Composite 模式重在表示。