본문 바로가기
C C++ - STL

STL - 15 STL contaner list 응용 - Composite pattern 활용

by violetoz 2014. 2. 13.
[STL-15] STL contaner list 응용 - Composite pattern 활용|STL을 배우자
2008.03.17 14:45

STL list container를 이용하며 Design pattern의 Composite : Object Structure를 이용한 간단한 예.

 

Composite pattern은

아래와 같이 Tree 아래 데이터와 Tree가 추가 되는 형태로 데이터와 list를 같은 등급에서 처리하는형태로

일반적인 tree나 list 같은 자료 구조로는 처리하기 어려운 부분이 있습니다.

이러한 구조에 대하여 효율적인 처리를 할 수 있는 pattern이 coposite pattern 입니다.

 

 

설계는 아래와 같은 구조로 합니다.

 

 

작성한 예는 아래와 같은 형태로 자료를 생성 관리 하도록 하였습니다.

설계 구조와 소스 코드를 참고해서 보시기 바랍니다.

 

   DataSet

   |

   +----------+----------+----------+

   |          |          |          |

   Data1      Data2      DataSet    Data1

                         |

                         +----------+----------+

                         |          |          |

                         Data1      Data2      DataSet
                                               |

                                               +

                                               |

                                               Data1

 

 

 

 

  1 /*
  2     eng'r : Jeong-il Ahn ( raon_pgm@naver.com )
  3 */
  4 
  5 #include <iostream>
  6 #include <iomanip>
  7 #include <algorithm>
  8 #include <list>
  9 #include <string>
 10 
 11 // Function Object - delete object
 12 struct FODeleteObject{
 13     template < typename T >
 14         void operator()( const T* ptr ) const { delete ptr; }
 15 };
 16 
 17 class Composite;
 18 
 19 class Component{
 20 public:
 21     virtual ~Component(){}
 22 
 23     virtual void Add( Component* pdata ){}
 24 
 25     virtual void Print( std::ostream& os )
 26     {
 27         os << "Component : " << str_ << std::endl;
 28     }
 29     
 30     virtual Composite* GetComposite()
 31     {
 32         return 0;
 33     }
 34 
 35 protected:
 36     Component( const std::string& s = "OriginalComponent" )
 37     {
 38         str_ = s;
 39     }
 40 
 41 private:
 42     std::string str_;
 43 };
 44 
 45 class Composite : public Component{
 46 public:
 47 
 48     virtual ~Composite()
 49     {
 50         for_each( listComponent_.begin(), listComponent_.end(), FODeleteObject() );
 51     }
 52 
 53     virtual void Add( Component* pdata )
 54     {
 55         listComponent_.push_back(pdata);
 56     }
 57 
 58     virtual void Print( std::ostream& os )
 59     {
 60         os << "Composite - " << str_ << " start" << std::endl;
 61         for( std::list< Component* >::iterator i = listComponent_.begin() ; i != listComponent_.end() ; ++i ){
 62             (*i)->Print( os );
 63         }
 64         os << "Composite - " << str_ << " end" << std::endl;
 65     }
 66 
 67     virtual Composite* GetComposite()
 68     {
 69         return this;
 70     }
 71 
 72 protected:
 73     Composite( const std::string& str = "OriginalComposite" ) : Component(str), str_(str) {}
 74 
 75 private:
 76     std::string str_;
 77     std::list< Component* > listComponent_;
 78 };
 79 
 80 class Data1 : public Component{
 81 public:
 82     Data1( const std::string& str = "data1type" ) : Component( str ) {}
 83 };
 84 
 85 class Data2 : public Component{
 86 public:
 87     Data2( const std::string& str = "data2type" ) : Component( str ) {}
 88 };
 89 
 90 class DataSet : public Composite{
 91 public:
 92     DataSet( const std::string& str = "dset" ) : Composite(str) {}
 93 };
 94 
 95 
 96 using namespace std;
 97 
 98 int main()
 99 {
100     DataSet* dataset = new DataSet("ComponentA");
101     Component* ComponentA = dataset;
102 
103     Data1* d1 = new Data1("d1_Object");
104     Data2* d2 = new Data2("d2_Object");
105 
106     ComponentA->Add( d1 );
107     ComponentA->Add( d2 );
108 
109     DataSet* dset1 = new DataSet("DataSet1");
110     
111     ComponentA->Add( dset1 );
112     
113     Data1* dd1 = new Data1("dd1_Object");
114     Data2* dd2 = new Data2("dd2_Object");
115     dset1->Add( dd1 );
116     dset1->Add( dd2 );
117 
118     DataSet* ddset1 = new DataSet("Sub DataSet of DataSet1");
119     Data1* ddd1 = new Data1("ddd1_Object");
120     ddset1->Add( ddd1 );
121     dset1->Add( ddset1 );
122 
123     Data1* d1another = new Data1("d1another_Object");
124 
125     ComponentA->Add( d1another );
126 
127     ComponentA->Print( cout );
128 
129     return EXIT_SUCCESS;
130 }
131