//
Purpose.  Composite                  // Strategy.  Use recursive composition
                                        // to
create a heterogeneous aggregate
#include <string.h>                     // that can be treated
homogeneously.
enum NodeType { FileT, DirT };          //
int 
g_indent = 0;                     
// Benefit.  No more type
checking and
                                        // type casting (coupling
between Dir
class File {                            // and File is gone, Dir is only
public:                                 // coupled to
abstract base class)
   File( char*
n ) { type_ = FileT;
      strcpy(
name_, n ); }             class AbsFile
{
   NodeType getType() { return
type_; } public:
   void ls()
{                             virtual
void ls() = 0;
      for (int i=0;
i < g_indent; i++)  protected:
         cout << ' ';                      char        name_[20];
      cout << name_ << endl;
}             static int  indent_;
private:                                };
   NodeType 
type_;                     int
AbsFile::indent_ = 0;
   char      name_[20];
};                                      class
File: public AbsFile {
                                        public:
class Dir
{                                File(
char* n ) {
public:                                       strcpy( name_, n ); }
   Dir( char* n ) { type_ = DirT;          void ls() {
      strcpy( name_, n ); total_ = 0; }       for (int i=0; i < indent_;
i++)
   NodeType getType() { return
type_; }          cout << '
';
   void add( File* f ) {                      cout << name_
<< endl; }
     
files_[total_++] = f;            
};
   }
   void ls() {                          class Dir : public AbsFile {
      for (int i=0; i < g_indent; i++)  public:
         cout << ' ';                      Dir( char* n ) {
      cout << name_ <<
":" << endl;          
strcpy( name_, n ); total_ = 0; }
      g_indent += 3;                       void add( AbsFile* f ) {
      for (int i=0; i < total_; i++)          files_[total_++] = f; }
         if (files_[i]->getType()          void ls() {
               == DirT)                       for (int i=0; i <
indent_; i++)
            ((Dir*)
files_[i])->ls();            cout
<< ' ';
         else                                 cout <<
name_ << ":" << endl;
            files_[i]->ls();                  indent_ += 3;
      g_indent -= 3; }                        for (int i=0; i < total_; i++)
private:                                        
files_[i]->ls();
  
NodeType  type_;                           indent_ -= 3; }
   char      name_[20];                 private:
   File*    
files_[10];                  
AbsFile*  files_[10];
   int      
total_;                      
int       total_;
};                                      };
void
main( void )                       void
main( void )
{                                       {
   Dir  
one("1"), two("2"), thr("3");     Dir  
one("1"), two("2"), thr("3");
   File 
a("a"), b("b"), c("c"),           File  a("a"), b("b"), c("c"),
         d("d"), e("e");                         d("d"), e("e");
   one.add( &a );                          one.add( &a
);
   one.add( (File*) &two
);                one.add( &two
);
   one.add( &b );                          one.add( &b
);
   two.add( &c );                          two.add( &c
);
   two.add( &d );                          two.add( &d
);
   two.add( (File*) &thr
);                two.add( &thr
);
   thr.add( &e );                          thr.add( &e
);
   one.ls();                               one.ls();
}                                       }
// 1:          //       d               //
1:          //       d
//    a        //       3:             
//    a        //       3:
//    2:      
//          e            //    2:       //          e
//       c     //    b                  //       c     //   
b
// Purpose.  Composite design pattern
//
// 1. Identify the
scalar/primitive classes and vector/container classes
// 2. Create an
"interface" (lowest common denominator) that can make all
//    concrete classes
"interchangeable"
// 3. All concrete classes declare an "is
a" relationship to the interface
// 4. All "container"
classes couple themselves to the interface (recursive
//    composition, Composite "has a"
set of children up the "is a" hierarchy)
// 5.
"Container" classes use polymorphism as they delegate to their
children
#include <iostream>
#include
<vector>
using namespace std;
// 2. Create an
"interface" (lowest common denominator)
class Component {
public: virtual void traverse() = 0; };
class Leaf : public
Component {        // 1. Scalar
class   3. "isa"
relationship
   int value;
public:
   Leaf( int val ) { value = val; }
   void traverse() { cout << value
<< ' '; }
};
class Composite : public Component {   // 1. Vector class   3. "isa" relationship
   vector<Component*> children;        // 4. "container" coupled to
the interface
public:
   // 4.
"container" class coupled to the interface
   void add( Component* ele ) {
children.push_back( ele ); }
  
void traverse() {
      for
(int i=0; i < children.size(); i++)
         // 5. Use polymorphism to delegate to children
         children[i]->traverse();
}  };
void main( void ) {
   Composite containers[4];
   for (int i=0; i < 4; i++)
      for (int j=0; j < 3; j++)
         containers[i].add( new Leaf( i * 3 +
j ) );
   for (i=1; i < 4;
i++)
      containers[0].add(
&(containers[i]) );
  
for (i=0; i < 4; i++) {
     
containers[i].traverse();
     
cout << endl;
} 
}
// 0 1 2 3 4 5 6 7 8 9 10 11
// 3 4 5
// 6 7
8
// 9 10 11
// Purpose.  Composite design pattern - multiple
container classes
#include <iostream>
#include
<vector>
using namespace std;
class Component { public:
virtual void traverse() = 0; };
class Primitive : public Component
{
   int value;
public:
   Primitive( int val ) { value = val; }
   void traverse()      { cout << value << "  "; }
};
class Composite
: public Component {
  
vector<Component*> children;
   int               
value;
public:
  
Composite( int val )     { value
= val; }
   void add( Component* c
) { children.push_back( c ); }
  
void traverse() {
      cout
<< value << " 
";
      for (int i=0;
i < children.size(); i++)
         
children[i]->traverse();
} 
};
class Row : public Composite { public:     // Two different kinds of
"con-
   Row( int val ) :
Composite( val ) { }   // tainer"
classes.  Most of the
   void traverse() {                       // "meat" is in the
Composite
      cout <<
"Row";                      
// base class.
     
Composite::traverse();
} 
};
class Column : public Composite { public:
   Column( int val ) : Composite( val ) {
}
   void traverse() {
      cout << "Col";
      Composite::traverse();
}  };
void main( void ) {
      Row   
first( 1 );                    
// Row1
      Column second(
2 );                    //   |
      Column third( 3 );                     //  
+-- Col2
      Row    fourth( 4 );                    //  
|     |
      Row   
fifth( 5 );                    
//   |     +-- 7
     
first.add( &second );                  //   +-- Col3
      first.add( &third  );                  //  
|     |
      third.add( &fourth );                  //   |     +-- Row4
      third.add( &fifth  );                  //  
|     |     |
     
first.add(  &Primitive( 6 )
);         //   |     |     +-- 9
      second.add( &Primitive( 7 ) );         //   |     +-- Row5
      third.add( 
&Primitive( 8 ) );        
//   |     |     |
      fourth.add( &Primitive( 9 ) );         //  
|     |     +-- 10
     
fifth.add(  &Primitive(10 )
);         //   |     +-- 8
      first.traverse(); 
cout << '\n';       //   +-- 6
}
// Row1  Col2 
7  Col3  Row4  9  Row5 
10  8  6
// Purpose.  Composite and Prototype - lightweight
persistence
#pragma warning( disable : 4786 )
#include
<iostream>
#include <vector>
#include
<string>
#include <map>
#include <fstream>
using
namespace std;
class Component { public:
   virtual ~Component() { }
   virtual void       traverse() = 0;
  
virtual Component* clone() = 0;
  
virtual void       initialize(
ifstream& ) = 0;
};
namespace Factory {
   map<string,Component*> hash;
   void add( string s, Component* c ) {
hash[s] = c; }
   Component*
makeComponent( string name ) { return hash[name]->clone(); }
}
class
Leaf : public Component {
   string
value;
public:
   ~Leaf()                           { cout << 'd'
<< value << ' '; }
  
/*virtual*/ void       traverse()
{ cout << value << ' '; }
  
/*virtual*/ Component* clone()   
{ return new Leaf(); }
  
/*virtual*/ void      
initialize( ifstream& is ) { is >> value; }
};
class
Composite : public Component {
  
vector<Component*> children;
   string            
value;
public:
  
~Composite() {
      cout
<< 'd' << value << ' ';
      for (int i=0; i < children.size(); i++)
          delete children[i];
   }
  
void add( Component* c ) { children.push_back( c ); }
   /*virtual*/ void traverse() {
      cout << value << ' ';
      for (int i=0; i < children.size();
i++)
         
children[i]->traverse();
  
}
   /*virtual*/ Component*
clone() { return new Composite(); }
  
/*virtual*/ void      
initialize( ifstream& is ) {
      is >> value;
     
string str, delim( "/"+value );
      is >> str;
      while (str != delim) {
         add( Factory::makeComponent( str )
);
        
children[children.size()-1]->initialize( is );
         is >> str;
}  } 
};
void main( void ) {
   Factory::add( "comp", new Composite() );
   Factory::add( "leaf", new Leaf()
);
   ifstream is(
"compositeCreate.txt" );
  
string str;
   is >>
str;
   Component* root =
Factory::makeComponent( str );
  
root->initialize( is );
  
root->traverse();  cout
<< '\n';
   delete root;       cout << '\n';
}
/***
comp
a leaf 1 comp b comp d leaf 8 leaf 9 /d leaf 4 comp e leaf 10
leaf 11 leaf
12 /e leaf 2 comp c leaf 5 leaf 6 leaf 7 /c /b leaf 3 /a
***/
//
a 1 b d 8 9 4 e 10 11 12 2 c 5 6 7 3
// da d1 db dd d8 d9 d4 de d10 d11
d12 d2 dc d5 d6 d7 d3