//
Purpose.  Inheritance run amok
public
class DecoratorBefore {
static class A { public void doIt() {
System.out.print( 'A' ); } }
static class AwithX extends A {
   public 
void doIt() { super.doIt(); 
doX(); }
   private void
doX()  { System.out.print( 'X' );
}
}
static class AwithY extends A {
   public void doIt() { super.doIt();  doY(); }
   public void doY()  {
System.out.print( 'Y' ); }
}
static class AwithZ extends A
{
   public void doIt() {
super.doIt();  doZ(); }
   public void doZ()  { System.out.print( 'Z' ); }
}
static class
AwithXY extends AwithX {
   private
AwithY obj = new AwithY();
  
public void doIt() {
     
super.doIt();
     
obj.doY();
}  }
static
class AwithXYZ extends AwithX {
  
private AwithY obj1 = new AwithY();
   private AwithZ obj2 = new AwithZ();
   public void doIt() {
      super.doIt();
      obj1.doY();
      obj2.doZ();
}  }
public static void main(
String[] args ) {
   A[] array = {
new AwithX(), new AwithXY(), new AwithXYZ() };
   for (int i=0; i < array.length; i++) {
      array[i].doIt();
      System.out.print( "  " );
}  }  }
// AX  AXY 
AXYZ
// Purpose. 
Decorator design pattern
public class DecoratorAfter {
interface
I { void doIt(); }
static class A implements I { public void doIt()
{ System.out.print( 'A' ); } }
static abstract class D implements I
{
   private I core;
   public D( I inner ) { core = inner; }
   public void doIt()  { core.doIt();  }
}
static class X extends D {
   public X( I inner ) { super( inner );
}
   public void doIt()  {
     
super.doIt();
     
doX();
   }
   private void doX() { System.out.print( 'X'
); }
}
static class Y extends D {
   public Y( I inner ) { super( inner );
}
   public void doIt()  {
     
super.doIt();
     
doY();
   }
   private void doY() { System.out.print( 'Y'
); }
}
static class Z extends D {
   public Z( I inner ) { super( inner );
}
   public void doIt()  {
     
super.doIt();
     
doZ();
   }
   private void doZ() { System.out.print( 'Z'
); }
}
public static void main( String[] args ) {
   I[]
array = { new X( new A() ), new Y( new X( new A() ) ),
                 new Z( new Y( new X( new A()
) ) ) };
   for (int i=0; i <
array.length; i++) {
     
array[i].doIt();
     
System.out.print( "  "
);
}  }  }
// AX 
AXY  AXYZ
//
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
interface
Widget { void draw(); }             //
1. "lowest common denominator"
class TextField implements
Widget {           // 3.
"Core" class with "isa" rel
   private int width, height;
   public TextField( int w, int h ) {
      width 
= w;
      height = h;
   }
  
public void draw() {
     
System.out.println( "TextField: " + width + ", " +
height );
}  }
                                               
// 2. Second level base class
abstract class Decorator implements
Widget {    //    with "isa" relationship
   private Widget wid;                          // 4.
"hasa" relationship
  
public Decorator( Widget w ) { wid = w; }
   public void draw()           { wid.draw(); } // 5. Delegation
}
class
BorderDecorator extends Decorator {         
// 6. Optional embellishment
  
public BorderDecorator( Widget w ) {
      super( w );
  
}
   public void draw()
{
      super.draw();                                // 7. Delegate
to base class
     
System.out.println( "  
BorderDecorator" );  //    and add extra stuff
}  }
class ScrollDecorator extends
Decorator {          // 6. Optional
embellishment
   public
ScrollDecorator( Widget w ) {
     
super( w );
   }
   public void draw() {
      super.draw();                                // 7. Delegate to base class
      System.out.println( "   ScrollDecorator" );  //   
and add extra stuff
} 
}
public class DecoratorDemo {
   public static void main( String[] args )
{
      // 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
//
Decorator - authenticate, input, encrypt, authenticate, decrypt, output
import
java.io.*;
public class DecoratorStream {
  static BufferedReader in = new
BufferedReader( new InputStreamReader( System.in ) );
  interface LCD {
    void write( String[] s );
    void read(  String[] s );
 
}
  static class Core
implements LCD {
    public void
write( String[] s ) {
     
System.out.print( "INPUT:   
" );
      try {
        s[0] = in.readLine();
      } catch (IOException ex) {
ex.printStackTrace(); }
    }
    public void read( String[] s ) {
      System.out.println( "Output:   " + s[0] );
  } }
  static class Decorator implements LCD {
    private LCD inner;
    public Decorator( LCD i ) { inner = i;
}
    public void write( String[] s
) { inner.write( s ); }
    public
void read(  String[] s ) {
inner.read(  s ); }
  }
  static class Authenticate extends Decorator {
    public Authenticate( LCD inner ) { super(
inner ); }
    public void
write(  String[] s ) {
      System.out.print( "PASSWORD: "
);
      try {
        in.readLine();
      } catch (IOException ex) {
ex.printStackTrace(); }
     
super.write( s );
   
}
    public void read(
String[] s ) {
     
System.out.print( "PASSWORD: " );
      try {
        in.readLine();
     
} catch (IOException ex) { ex.printStackTrace(); }
      super.read( s );
  } }
  static class Scramble extends Decorator {
    public Scramble( LCD inner ) { super(
inner ); }
    public void write(
String[] s ) {
      super.write( s
);
      System.out.println(
"encrypt:" );
     
StringBuffer sb = new StringBuffer( s[0] );
      for (int i=0; i < sb.length();
i++)
        sb.setCharAt( i,
(char) (sb.charAt( i ) - 5) );
     
s[0] = sb.toString();
   
}
    public void read(
String[] s ) {
      StringBuffer
sb = new StringBuffer( s[0] );
     
for (int i=0; i < sb.length(); i++)
        sb.setCharAt( i, (char) (sb.charAt( i ) + 5) );
      s[0] = sb.toString();
      System.out.println( "decrypt:"
);
      super.read( s );
  } }
  public static void main( String[] args ) {
    LCD stream = new Authenticate( new
Scramble( new Core() ) );
   
String[] str = { new String() };
    stream.write( str );
   
System.out.println( "main:    
" + str[0] );
   
stream.read( str );
} }
// PASSWORD: secret
//
INPUT:    the quick brown fox
//
encrypt:
// main:     oc`lpd^f]mjriajs
//
PASSWORD: secret
// decrypt:
// Output:   the quick brown fox