Composite 模式的实现
实现要点:
1.组合模式采用树形结构来实现普遍存在的对象容器,从而将“一对多”的关系转化“一对一”的关系,使得客户代码可以一致地处理对象和对象容器,无需关心处理的是单个的对象,还是组合的对象容器。
2.将“客户代码与复杂的对象容器结构”解耦是组合模式的核心思想,解耦之后,客户代码将与纯粹的抽象接口——而非对象容器的复内部实现结构——发生依赖关系,从而更能“应对变化”。
3.组合模式中,是将“Add和Remove等和对象容器相关的方法”定义在“表示抽象对象的Component类”中,还是将其定义在“表示对象容器的Composite类”中,是一个关乎“透明性”和“安全性”的两难问题,需要仔细权衡。这里有可能违背面向对象的“单一职责原则”,但是对于这种特殊结构,这又是必须付出的代价。
4.组合模式在具体实现中,可以让父对象中的子对象反向追溯;如果父对象有频繁的遍历需求,可使用缓存技巧来改善效率。
5. 客户端尽量不要直接调用树叶类的方法,而是借助其父类(Component)的多态性完成调用,这样可以增加代码的复用性。
使用场景:
以下情况下适用组合模式:
1.你想表示对象的部分-整体层次结构。
2.你希望用户忽略组合对象与单个对象的不同,用户将统一地使用组合结构中的所有对象。
/////////////////Component.h////////////////////////
1 #pragma once 2 class Component 3 { 4 public: 5 virtual ~Component(); 6 Component(); 7 virtual void Operation() = 0 ; 8 virtual void Add( Component*); 9 virtual void Remove( Component*); 10 virtual Component* GetChild(int); 11 protected: 12 private: 13 };
1 /////////////////Component.cpp//////////////////////// 2 #include "Component.h" 3 Component::Component() 4 { 5 6 } 7 Component::~Component() 8 { 9 10 } 11 void Component::Add( Component* com) 12 { 13 14 } 15 16 void Component::Remove( Component* com) 17 { 18 19 } 20 void Component::Operation() 21 { 22 23 } 24 Component* Component::GetChild(int index) 25 { 26 return 0; 27 }
1 /////////////////Composite.h//////////////////////// 2 #pragma once 3 #include "Component.h" 4 #include <vector> 5 using namespace std; 6 class Composite : public Component 7 { 8 public: 9 Composite(const string&); 10 ~Composite(); 11 void Operation() ; 12 void Add( Component*); 13 void Remove( Component*); 14 Component* GetChild(int); 15 protected: 16 private: 17 vector<Component*> comVec ; 18 string _name ; 19 };
1 /////////////////Composite.cpp//////////////////////// 2 #include "Composite.h" 3 #include "Component.h" 4 #include <iostream> 5 #include <string> 6 using namespace std; 7 8 Composite::Composite(const string& name) 9 { 10 _name = name ; 11 } 12 Composite::~Composite() 13 { 14 15 } 16 void Composite::Operation() 17 { 18 cout<<"Composite operation : "<<_name<<endl; 19 vector<Component*>::iterator iter = comVec.begin(); 20 for (;iter != comVec.end() ; iter++) 21 { 22 23 if (_name == "Com2") 24 { 25 cout<<"------"; 26 } 27 if (_name == "Com1") 28 { 29 cout<<"---"; 30 } 31 32 (*iter)->Operation(); 33 } 34 35 } 36 void Composite::Add( Component* com) 37 { 38 comVec.push_back(com); 39 } 40 void Composite::Remove( Component* com) 41 { 42 for (vector<Component*>::iterator it = comVec.begin() ; it != comVec.end() ;) 43 { 44 if (com == *it) 45 { 46 it = comVec.erase(it); 47 } 48 else 49 { 50 it++; 51 } 52 } 53 } 54 55 Component* Composite::GetChild(int index) 56 { 57 return comVec[index] ; 58 }
1 ////////////////////Leaf.h/////////////////////// 2 #pragma once 3 #include "Component.h" 4 #include <iostream> 5 #include <string> 6 using namespace std; 7 class Leaf : public Component 8 { 9 public: 10 Leaf(const string&); 11 ~Leaf(); 12 void Operation(); 13 protected: 14 private: 15 string _name; 16 }; 17 18 Leaf::Leaf(const string& name) 19 { 20 _name = name ; 21 } 22 Leaf::~Leaf() 23 { 24 25 } 26 void Leaf::Operation() 27 { 28 cout<<"Leaf operation : "<< _name <<endl; 29 }
1 /////////////////main//////////////////////////// 2 #include "Component.h" 3 #include "Composite.h" 4 #include "Leaf.h" 5 #include <iostream> 6 #include <string> 7 using namespace std; 8 9 int main() 10 { 11 Component* leaf1 = new Leaf("leaf1") ; 12 Component* leaf2 = new Leaf("leaf2") ; 13 Component* leaf3 = new Leaf("leaf3") ; 14 Component* com1 = new Composite("Com1"); 15 com1->Add(leaf1); 16 com1->Add(leaf2); 17 com1->Add(leaf3); 18 19 Component* leaf4 = new Leaf("leaf4") ; 20 Component* leaf5 = new Leaf("leaf5") ; 21 Component* com2 = new Composite("Com2"); 22 com2->Add(leaf4); 23 com2->Add(leaf5); 24 25 com1->Add(com2); 26 27 com1->Operation(); 28 29 getchar(); 30 return 0; 31 }