組合模式,是爲了解決總體和部分的一致對待的問題而產生的,要求這個總體與部分有一致的操做或行爲。部分和總體都繼承與一個公共的抽象類,這樣,外部使用它們時是一致的,不用管是總體仍是部分,使用一個方法便可遍歷總體中的全部的部分。就像一個樹形結構同樣。ide
以下面的類圖,client的只須要使用Component便可,無須關心究竟是Leaf仍是Composite。函數
這裏有兩種狀況,add函數對於Leaf來講是沒有必要的,因此一種辦法就是在Leaf的add實現中什麼都不寫。spa
還一種辦法就是將add方法挪到Composite中,讓外部使用Composite和Component。但這樣的缺點就是暴露了Composite,客戶端必須知道Composite才能完成操做,好處Leaf不用產生多餘的方法了。code
經常使用於組織結構,產品結構之類的總體和部分的結構。例如圖形由不少直線構成,直線由點構成,這就是總體和部分的關係。若是採用組合模式,只須要使用一個draw方法便可按遍歷的方式畫出全部的點,最終呈現出來的就是圖形。blog
1.隱藏了總體和部分,讓外部依賴於抽象,簡化了代碼。繼承
1.要求必須有一致的行爲。get
2.處於同一個Composite的Leaf與Leaf之間難以傳遞數據。產品
1 #ifndef _COMPONENT_H_ 2 #define _COMPONENT_H_ 3 4 #include <vector> 5 #include <stdio.h> 6 7 using namespace std; 8 9 class Component 10 { 11 public: 12 Component(){}; 13 virtual ~Component(){}; 14 15 virtual void operation() = 0; 16 }; 17 18 19 20 class Leaf: public Component 21 { 22 public: 23 Leaf(){}; 24 ~Leaf(){}; 25 26 void operation(); 27 }; 28 29 30 class Composite: public Component 31 { 32 public: 33 Composite(){}; 34 ~Composite(){}; 35 36 void add(Component*); 37 void operation(); 38 39 private: 40 vector<Component*> m_leafs; 41 }; 42 43 #endif
1 #include "Component.h" 2 3 4 5 void Leaf::operation() 6 { 7 fprintf(stderr, "----operation leaf\n"); 8 } 9 10 11 void Composite::add(Component* c) 12 { 13 m_leafs.push_back(c); 14 } 15 16 17 18 void Composite::operation() 19 { 20 fprintf(stderr, "operation Composite\n"); 21 vector<Component*>::iterator comIter = m_leafs.begin(); 22 23 for (; comIter != m_leafs.end(); comIter++) 24 { 25 fprintf(stderr, "----"); 26 (*comIter)->operation(); 27 } 28 }
1 #include "Component.h" 2 3 4 int main() 5 { 6 Component* leaf1 = new Leaf(); 7 Component* leaf2 = new Leaf(); 8 9 Composite* composite1 = new Composite(); 10 composite1->add(leaf1); 11 composite1->add(leaf2); 12 13 Composite* composite2 = new Composite(); 14 composite2->add(composite1); 15 16 composite2->operation(); 17 return 0; 18 }
1 g++ -o client client.cpp Component.cpp
運行結果it