//
Purpose.  Decorator design pattern
//
1. Create a "lowest common denominator" that makes classes
interchangeable
// 2. Create a second level base class for optional
functionality
// 3. "Core" class and "Decorator" class
declare an "isa" relationship
// 4. Decorator class
"hasa" instance of the "lowest common denominator"
//
5. Decorator class delegates to the "hasa" object
// 6. Create a
Decorator derived class for each optional embellishment
// 7. Decorator
derived classes delegate to base class AND add extra stuf
// 8. Client has
the responsibility to compose desired configurations
#include
<iostream>
using namespace std;
class Widget { public:
virtual void draw() = 0; };  // 1.
"lowest common denom"
class TextField : public Widget
{                   // 3.
"Core" class & "isa"
   int width, height;
public:
   TextField( int w, int h ) { width  = w;  height = h; }
   /*virtual*/ void draw() { cout <<
"TextField: " << width << ", " << height
<< '\n'; }
};
                                                    // 2. 2nd level base class
class
Decorator : public Widget {                  
// 3. "isa" relationship
   Widget* wid;                                     // 4. "hasa"
relationship
public:
  
Decorator( Widget* w )  { wid =
w; }
   /*virtual*/ void draw() {
wid->draw(); }         // 5.
Delegation
};
class BorderDecorator : public Decorator {
public:  // 6. Optional
embellishment
   BorderDecorator(
Widget* w ) : Decorator( w ) { }
  
/*virtual*/ void draw() {
     
Decorator::draw();               
            // 7. Delegate to
base class
      cout <<
"   BorderDecorator" <<
'\n';         //    and add extra stuff
}  };
class ScrollDecorator : public
Decorator { public:  // 6. Optional
embellishment
   ScrollDecorator(
Widget* w ) : Decorator( w ) { }
  
/*virtual*/ void draw() {
     
Decorator::draw();                            // 7. Delegate to base class
      cout << "   ScrollDecorator" << '\n';         //   
and add extra stuff
} 
};
void main( void ) {
   // 8. Client has the responsibility to compose desired
configurations
   Widget* aWidget =
new BorderDecorator(
                        new BorderDecorator(
                           new
ScrollDecorator(
                              new TextField( 80, 24 ))));
   aWidget->draw();
}
//
TextField: 80, 24
//   
ScrollDecorator
//   
BorderDecorator
//   
BorderDecorator
// Purpose.  Inheritance run amok
#include
<iostream>
using namespace std;
class A { public:
   virtual void doIt() { cout << 'A';
}
};
class AwithX : public A {
   void doX() { cout << 'X'; }
public:
   /*virtual*/ void doIt() {
      A::doIt();
      doX();
}  };
class AwithY : public A {
protected:
   void doY() { cout << 'Y'; }
public:
   /*virtual*/ void doIt() {
      A::doIt();
      doY();
}  };
class AwithZ : public A {
protected:
   void doZ() { cout << 'Z'; }
public:
   /*virtual*/ void doIt() {
      A::doIt();
      doZ();
}  };
class AwithXY : public AwithX, public AwithY {
public:
   /*virtual*/ void doIt()
{
      AwithX::doIt();
      AwithY::doY();
}  };
class AwithXYZ : public
AwithX, public AwithY, public AwithZ { public:
   /*virtual*/ void doIt() {
      AwithX::doIt();
     
AwithY::doY();
     
AwithZ::doZ();
}  };
void
main( void ) {
   AwithX    anX;
   AwithXY   anXY;
   AwithXYZ 
anXYZ;
   anX.doIt();    cout << '\n';
   anXY.doIt();   cout << '\n';
  
anXYZ.doIt();  cout <<
'\n';
}
// AX
// AXY
// AXYZ
//
Purpose.  Replacing inheritance with
wrapping-delegation
//
// Discussion.  Use aggregation instead of inheritance to implement
//
embellishments to a "core" object. 
Client can dynamically compose
// permutations, instead of the
architect statically wielding multiple
// inheritance.
#include
<iostream>
using namespace std;
class I { public:
   virtual ~I() { }
   virtual void doIt() = 0;
};
class
A : public I { public:
   ~A() {
cout << "A dtor" << '\n'; }
   /*virtual*/ void doIt() { cout <<
'A'; }
};
class D : public I {
   I* wrappee;
public:
  
D( I* inner )           { wrappee
= inner; }
   ~D()                    { delete wrappee; }
   /*virtual*/ void doIt() {
wrappee->doIt(); }
};
class X : public D { public:
   X( I* core ) : D(core) { }
   ~X() { cout << "X dtor"
<< "   "; }
   /*virtual*/ void doIt() { D::doIt();  cout << 'X'; }
};
class
Y : public D { public:
   Y( I*
core ) : D(core) { }
   ~Y() { cout
<< "Y dtor" << "  
"; }
   /*virtual*/
void doIt() { D::doIt();  cout <<
'Y'; }
};
class Z : public D { public:
   Z( I* core ) : D(core) { }
   ~Z() { cout << "Z dtor"
<< "   "; }
   /*virtual*/ void doIt() { D::doIt();  cout << 'Z'; }
};
void
main( void ) {
   I* anX = new X(
new A );
   I* anXY = new Y( new X(
new A ) );
   I* anXYZ = new Z( new
Y( new X( new A ) ) );
  
anX->doIt();    cout <<
'\n';
   anXY->doIt();   cout << '\n';
   anXYZ->doIt();  cout << '\n';
  
delete anX;   delete anXY;   delete anXYZ;
}
// AX
//
AXY
// AXYZ
// X dtor   A
dtor
// Y dtor   X dtor   A dtor
// Z dtor   Y dtor  
X dtor   A dtor
//
Purpose.  Decorator - encoding and
decoding layers of header/packet/trailer
#include <iostream>
#include
<string>
using namespace std;
class Interface {
public:
   virtual ~Interface() {
}
   virtual void write(
string& ) = 0;
   virtual void
read(  string& ) = 0;
};
class
Core : public Interface { public:
  
~Core() { cout << "dtor-Core\n"; }
   /*virtual*/ void write( string& b ) { b
+= "MESSAGE|"; }
  
/*virtual*/ void read( string& );
};
class Decorator
: public Interface {
   Interface*
inner;
public:
   Decorator(
Interface* c ) { inner = c; }
  
~Decorator()              {
delete inner; }
   /*virtual*/ void
write( string& b ) { inner->write( b ); }
   /*virtual*/ void read(  string& b ) { inner->read( b );
}
};
class Wrapper : public Decorator {
   string forward, backward;
public:
   Wrapper( Interface* c, string str ) :
Decorator(c) {
      forward =
str;
      string::reverse_iterator
it;
      it = str.rbegin();
      for ( ; it != str.rend(); ++it)
         backward += *it;
   }
  
~Wrapper() { cout << "dtor-" << forward <<
"  "; }
   void write( string& );
   void read( 
string& );
};
void main( void ) {
   Interface* object = new Wrapper( new
Wrapper( new Wrapper(
                          new Core(), "123" ),
"abc" ), "987" );
  
string buf;
  
object->write( buf );
  
cout << "main: " << buf << endl;
   object->read( buf );
   delete object;
}
// main:
987]abc]123]MESSAGE|321]cba]789]
// Wrapper: 987
// Wrapper:
abc
// Wrapper: 123
// Core: MESSAGE
// Wrapper: 321
//
Wrapper: cba
// Wrapper: 789
// dtor-987  dtor-abc  dtor-123  dtor-Core
void
Core::read(string& b) {
   int
num = b.find_first_of( '|' );
  
cout << "Core: " << b.substr(0,num) <<
'\n';
   b = b.substr(num+1);
}
void
Wrapper::write( string& b ) {
  
b += forward + "]";
  
Decorator::write( b );
   b
+= backward + "]";
}
void Wrapper::read( string&
b ) {
   int num = b.find_first_of(
']' );
   cout <<
"Wrapper: " << b.substr(0,num) << '\n';
   b = b.substr(num+1);
   Decorator::read( b );
   num = b.find_first_of( ']' );
   cout << "Wrapper: "
<< b.substr(0,num) << '\n';
  
b = b.substr(num+1);
}