首页 > 代码库 > Composite 模式的实现

Composite 模式的实现

实现要点:

1组合模式采用树形结构来实现普遍存在的对象容器,从而将一对多的关系转化一对一的关系,使得客户代码可以一致地处理对象和对象容器,无需关心处理的是单个的对象,还是组合的对象容器。

2.将客户代码与复杂的对象容器结构解耦是组合模式的核心思想,解耦之后,客户代码将与纯粹的抽象接口——而非对象容器的复内部实现结构——发生依赖关系,从而更能应对变化

3组合模式中,是将“AddRemove等和对象容器相关的方法定义在表示抽象对象的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 }