Composite 組合對象結構型模式:将對象組合成樹形結構以表示“部分-整體”的層次結構。Composite 使得使用者對單個對象群組合的使用具有一緻性。
Composite 模式适用于:1)你想表示對象的“部分-整體”層次結構。2)你希望使用者忽略組合對象與單個對象的不同,使用者将統一地使用組合結構中的所有對象。
Composite 的通用結構圖如下:
典型的 Composite 對象結構如下圖所示:
注:1)客戶通過 Component 接口操縱部件的對象。
2)Component: 為組合中的對象聲明接口;在适當的情況下,實作所有類共有接口的預設行為;聲明一個接口用于通路和管理 Component 的子元件。在遞歸結構中定義一個接口,用于通路一個父部件,并在合适的情況下實作它。
3)Leaf:在組合中表示葉節點對象,葉節點沒有子節點;在組合中定義對象行為。
4):Composite:定義有子部件的那些部件的行為;存儲子部件;在 Composite 接口中實作與子部件有關的操作。
其中:Add 和 Remove 操作用于管理子部件。1):如果強調透明性,則應該在類層次結構的根部Component 定義子節點管理接口 ,這樣可以一緻地使用所有的元件,但這一方法是以安全性為代價的,因為客戶有可能會做一些無意義的事情,例如在 Leaf 中增加或删除對象等。2):如果強調安全性,則在 Composite 類中定義管理子部件的方法,但這樣損失了透明性,因為 Leaf 和 Composite 具有不同的接口。GOF 的書中指出,這一模式應該強調透明性。
Composite 組合對象結構型模式代碼示例如下:
1: //Composite.h
2: #pragma once
3:
4: #include
5: #include
6:
7: // 組合中的抽象基類
8: class Component{
9: public:
10: Component(){}
11: virtual ~Component(){ }
12:
13: // 純虛函數, 隻提供接口, 沒有預設的實作
14: virtual void Operation() = 0;
15:
16: // 強調透明性,在層次結構的根部定義 Add 和 Remove 用于管理子部件
17: // 虛函數, 提供接口, 有預設的實作但是什麼都不做
18: virtual void Add(Component* pChild); //添加一個子元件
19: virtual void Remove(Component* pChild); //删除一個子元件
20: virtual Component* GetChild(int nIndex); //獲得子元件的指針
21:
22: // 當該結構中子類數目相對較少時,可以在基類中存放子類指針
23: // private:
24: // std::list
m_ListOfComponent;
25: };
26:
27: // 派生自 Component, 是其中的葉子元件的基類
28: // Leaf1, for test
29: class Leaf1 : public Component{
30: public:
31: Leaf1(){}
32: virtual ~Leaf1(){ }
33:
34: virtual void Operation();
35: };
36: // Leaf2, for test
37: class Leaf2 : public Component{
38: public:
39: Leaf2(){}
40: virtual ~Leaf2(){ }
41:
42: virtual void Operation();
43: };
44:
45: //
46: // Composite 派生自 Component, 是其中的含有子件的元件的基類
47: class Composite : public Component{
48: public:
49: Composite(){ }
50: virtual ~Composite();
51:
52: // 對所有 m_ListOfComponent,調用其 Operation()
53: virtual void Operation();
54:
55: virtual void Add(Component* pChild);
56: virtual void Remove(Component* pChild);
57: virtual Component* GetChild(int nIndex);
58:
59: private:
60: // Composite 可以使用多種資料結構存貯它們的子節點
61: // 包括連接配接清單、樹、數組和 hash 表。資料結構的選擇取決于效率。
62: // 沒有必要使用通用的資料結構,有時對于每個子節點, Composite
63: // 都有一個變量與之對應,這就要求 Composite 的每個子類都要實作自己的管理接口。
64:
65: // 這裡采用 list 容器去儲存子元件
66: std::list
m_ListOfComponent;
67: };
68:
69: // Derived from Composite, for test
70: class Leaf3 : public Composite{
71: public:
72: Leaf3(){}
73: virtual ~Leaf3(){ }
74:
75: virtual void Operation();
76: };
77: // Derived from Composite, for test
78: class Leaf4 : public Composite{
79: public:
80: Leaf4(){}
81: virtual ~Leaf4(){ }
82:
83: virtual void Operation();
84: };
1: // Composite.cpp
2: #include "Composite.h"
3: #include
4: #include
5:
6: // Component成員函數的實作
7: void Component::Add(Component* pChild){}
8: void Component::Remove(Component* pChild){}
9: Component* Component::GetChild(int nIndex){ return NULL;}
10:
11: // Leaf1 成員函數的實作, for test
12: void Leaf1::Operation(){
13: std::cout << "Operation by leaf1" << std::endl;
14: }
15: // Leaf2 成員函數的實作, for test
16: void Leaf2::Operation(){
17: std::cout << "Operation by leaf2" << std::endl;
18: }
19:
20: // Composite 成員函數的實作
21: Composite::~Composite(){
22: std::list
::iterator iter1, iter2, temp;
23:
24: for (iter1 = m_ListOfComponent.begin(),
25: iter2 = m_ListOfComponent.end(); iter1 != iter2;)
26: {
27: temp = iter1;
28: ++iter1;
29: delete (*temp);
30: }
31: m_ListOfComponent.clear();
32: }
33:
34: // Composite::Operation 對所有的
35: void Composite::Operation(){
36: //std::cout << "Operation by Composite" << std::endl;
37: std::list
::iterator iter1, iter2;
38: for (iter1 = m_ListOfComponent.begin(),
39: iter2 = m_ListOfComponent.end();iter1 != iter2;++iter1)
40: {
41: (*iter1)->Operation();
42: }
43: }
44: // Add, Remove 管理子部件
45: void Composite::Add(Component* pChild){
46: m_ListOfComponent.push_back(pChild);
47: }
48:
49: void Composite::Remove(Component* pChild){
50: std::list
::iterator iter;
51:
52: iter = find(m_ListOfComponent.begin(), m_ListOfComponent.end(), pChild);
53: if (m_ListOfComponent.end() != iter){
54: m_ListOfComponent.erase(iter);
55: }
56: }
57:
58: Component* Composite::GetChild(int nIndex){
59: if (nIndex <= 0 || nIndex > m_ListOfComponent.size())
60: return NULL;
61:
62: std::list
::iterator iter1, iter2;
63: int i;
64: for (i = 1, iter1 = m_ListOfComponent.begin(),
65: iter2 = m_ListOfComponent.end();iter1 != iter2;++iter1, ++i){
66: if (i == nIndex)
67: break;
68: }
69:
70: return *iter1;
71: }
72:
73: // Leaf3 成員函數的實作, for test
74: void Leaf3::Operation(){
75: std::cout << "Operation by leaf3" << std::endl;
76: }
77: // Leaf4 成員函數的實作, for test
78: void Leaf4::Operation(){
79: std::cout << "Operation by leaf4" << std::endl;
80: }
//test
1: //test.cpp
2: #include "Composite.h"
3: #include
4:
5: int main()
6: {
7: Component* pComponent = new Composite;
8: Leaf1 *pLeaf1 = new Leaf1();
9: Leaf2 *pLeaf2 = new Leaf2();
10:
11: Leaf3 *pLeaf3 = new Leaf3();
12: Leaf4 *pLeaf4 = new Leaf4();
13:
14: pComponent->Add(pLeaf1);
15: pComponent->Add(pLeaf2);
16: pComponent->Add(pLeaf3);
17: pComponent->Add(pLeaf4);
18:
19: pComponent->Operation();
20:
21: delete pComponent;
22:
23: return EXIT_SUCCESS;
24: }