//
Purpose.  Need to refactor to sort out
"interface vs implementation"
class StackArray {
    private int[] items = new int[12];
    private int   total = -1;
   
public void push( int i ) { if ( ! isFull()) items[++total] = i; }
    public boolean isEmpty()  { return total == -1; }
    public boolean isFull()   { return total == 11; }
    public int top() {
        if (isEmpty()) return -1;
        return items[total];
    }
   
public int pop() {
       
if (isEmpty()) return -1;
       
return items[total--];
}  
}
class StackList {
   
private Node last;
   
public void push( int i ) {
       
if (last == null)
           
last = new Node( i );
       
else {
            last.next
= new Node( i );
           
last.next.prev = last;
           
last = last.next;
    }   }
   
public boolean isEmpty() { return last == null; }
    public boolean isFull()  { return false; }
    public int top() {
        if (isEmpty()) return -1;
        return last.value;
    }
   
public int pop() {
       
if (isEmpty()) return -1;
       
int ret = last.value;
       
last = last.prev;
       
return ret;
}   }
class
StackFIFO extends StackArray {
   
private StackArray temp = new StackArray();
    public int pop() {
        while ( ! isEmpty())
            temp.push( super.pop() );
        int ret =  temp.pop();
       
while ( ! temp.isEmpty())
            push( temp.pop() );
        return ret;
} 
}
class StackHanoi extends StackArray {
    private int totalRejected = 0;
    public int reportRejected()   { return totalRejected; }
    public void push( int in ) {
        if ( ! isEmpty()  && 
in > top())
           
totalRejected++;
       
else super.push( in );
}  
}
class BridgeDisc {
   
public static void main( String[] args ) {
        StackArray[] stacks = { new
StackArray(), new StackFIFO(), new StackHanoi() };
        StackList    stack2 = new StackList();
        for (int i=1, num; i < 15; i++) {
            stacks[0].push( i );
            stack2.push( i );
            stacks[1].push( i );
        }
        java.util.Random rn
= new java.util.Random();
       
for (int i=1, num; i < 15; i++)
            stacks[2].push( rn.nextInt(20) );
        while ( ! stacks[0].isEmpty())
            System.out.print( stacks[0].pop()
+ "  " );
        System.out.println();
        while ( ! stack2.isEmpty())
            System.out.print( stack2.pop() +
"  " );
        System.out.println();
        while ( ! stacks[1].isEmpty())
            System.out.print( stacks[1].pop()
+ "  " );
        System.out.println();
        while ( ! stacks[2].isEmpty())
            System.out.print( stacks[2].pop()
+ "  " );
        System.out.println();
        System.out.println( "total
rejected is "
            +
((StackHanoi)stacks[2]).reportRejected() );
}   }
// 12 
11  10  9  8  7 
6  5  4  3  2 
1
// 14  13  12 
11  10  9  8  7 
6  5  4  3  2 
1
// 1  2  3 
4  5  6  7  8 
9  10  11  12
// 0  0 
1  12  16  18
// total
rejected is 8
class Node {
   
public int  value;
    public Node prev, next;
    public Node( int i ) { value = i; }
}
//
Purpose.  Bridge design pattern
//
1. Create an implementation/body abstraction
// 2. Derive the separate
implementations from the common abstraction
// 3. Create an
interface/handle class that "has a" and delegates to the impl
//
4. Embellish the interface class with derived classes if desired
class
Stack {
    private StackImpl
impl;
    public Stack( String s )
{
        if      (s.equals("array")) impl = new
StackArray();
        else if
(s.equals("list"))  impl = new
StackList();
        else System.out.println(
"Stack: unknown parameter" );
    }
    public
Stack()                { this(
"array" ); }
    public
void    push( int in ) { impl.push( in
); }
    public int     pop()          { return impl.pop(); }
    public int    
top()          { return
impl.top(); }
    public boolean
isEmpty()      { return impl.isEmpty();
}
    public boolean isFull()       { return impl.isFull(); }
}
class
StackHanoi extends Stack {
   
private int totalRejected = 0;
   
public StackHanoi()           {
super( "array" ); }
   
public StackHanoi( String s ) { super( s ); }
    public int reportRejected()   { return totalRejected; }
    public void push( int in ) {
        if ( ! isEmpty()  && 
in > top())
           
totalRejected++;
       
else super.push( in );
}  
}
class StackFIFO extends Stack {
    private StackImpl temp = new
StackList();
    public
StackFIFO()           { super(
"array" ); }
    public
StackFIFO( String s ) { super( s ); }
   
public int pop() {
       
while ( ! isEmpty())
          
 temp.push( super.pop() );
        int ret =  temp.pop();
       
while ( ! temp.isEmpty())
            push( temp.pop() );
        return ret;
} 
}
interface StackImpl {
    void    push( int i
);
    int     pop();
    int     top();
    boolean isEmpty();
    boolean isFull();
}
class
StackArray implements StackImpl {
   
private int[] items = new int[12];
    private int   total =
-1;
    public void push( int i ) {
if ( ! isFull()) items[++total] = i; }
   
public boolean isEmpty()  {
return total == -1; }
    public
boolean isFull()   { return total == 11;
}
    public int top() {
        if (isEmpty()) return -1;
        return items[total];
    }
   
public int pop() {
       
if (isEmpty()) return -1;
       
return items[total--];
}  
}
class StackList implements StackImpl {
    private Node last;
    public void push( int i ) {
        if (last == null)
            last = new Node( i );
        else {
            last.next = new Node( i );
            last.next.prev = last;
            last = last.next;
    }  
}
    public boolean
isEmpty() { return last == null; }
   
public boolean isFull()  { return
false; }
    public int top()
{
        if (isEmpty()) return
-1;
        return
last.value;
    }
    public int pop() {
        if (isEmpty()) return -1;
        int ret = last.value;
        last = last.prev;
        return ret;
}   }
class BridgeDisc {
    public static void main( String[] args )
{
        Stack[] stacks = { new
Stack( "array" ), new Stack( "list" ),
            new StackFIFO(), new StackHanoi()
};
        for (int i=1, num; i
< 15; i++)
            for (int
j=0; j < 3; j++)
               
stacks[j].push( i );
       
java.util.Random rn = new java.util.Random();
        for (int i=1, num; i < 15;
i++)
            stacks[3].push(
rn.nextInt(20) );
        for (int
i=0, num; i < stacks.length; i++) {
            while ( ! stacks[i].isEmpty())
                System.out.print(
stacks[i].pop() + "  "
);
           
System.out.println();
       
}
       
System.out.println( "total rejected is "
            +
((StackHanoi)stacks[3]).reportRejected() );
}   }
// 12 
11  10  9  8  7 
6  5  4  3  2 
1
// 14  13  12 
11  10  9  8  7 
6  5  4  3  2 
1
// 1  2  3 
4  5  6  7  8 
9  10  11  12
// 0  0 
1  12  16  18
// total
rejected is 8
class Node {
   
public int  value;
    public Node prev, next;
    public Node( int i ) { value = i; }
}
//
Purpose.  Bridge design pattern
//
1. Create an implementation/body base class
// 2. Derive the separate
implementations from the common abstraction
// 3. Create an
interface/wrapper class that "hasa" and delegates to the impl
//
4. Embellish the interface class with derived classes if desired
class
Stack {                  // 3. Create an
interface/wrapper class that
  
protected StackImp imp;    
//    "hasa"
implementation object and delegates
  
public Stack( String s ) { 
//    all requsts to it
      if (s.equals("java")) imp =
new StackJava();
      else                  imp = new StackMine();
}
   public Stack()                { this( "java" );
}
   public void    push( int in ) { imp.push( new Integer(in)
); }
   public int     pop()          { return ((Integer)imp.pop()).intValue(); }
   public boolean isEmpty()      { return imp.empty(); }
}
class
StackHanoi extends Stack {   // 4.
Embellish the interface class with
  
private int totalRejected = 0; 
//     derived classes if
desired
   public StackHanoi()           { super( "java" );
}
   public StackHanoi( String s )
{ super( s ); }
   public int
reportRejected()   { return totalRejected;
}
   public void push( int in )
{
      if ( ! imp.empty()  && 
in > ((Integer)imp.peek()).intValue())
         totalRejected++;
      else imp.push( new Integer(in) );
}  }
interface StackImp {           // 1. Create an implementation/body
base class
   Object  push( Object o );   Object  peek();
   boolean empty();            Object  pop();
}
class StackJava extends java.util.Stack implements StackImp {
}
class StackMine implements StackImp {        // 2. Derive the separate impl's
   private Object[] items = new
Object[20];  //    from the common abstraction
   private int      total = -1;
  
public Object push( Object o ) { return items[++total] = o; }
   public Object peek()           { return items[total]; } 
   public Object pop()            { return items[total--]; }
   public boolean empty()         { return total == -1; }
}
class
BridgeDemo {
   public static void
main( String[] args ) {
     
Stack[] stacks = { new Stack("java"), new
Stack("mine"), 
        
new StackHanoi("java"), new StackHanoi("mine")
};
      for (int i=0, num; i <
20; i++) {
         num = (int)
(Math.random() * 1000) % 40;
        
for (int j=0; j < stacks.length; j++) stacks[j].push( num );
      }
      for (int i=0, num; i < stacks.length; i++) {
         while ( ! stacks[i].isEmpty())
            System.out.print( stacks[i].pop()
+ "  " );
         System.out.println();
      }
      System.out.println( "total rejected is "
         +
((StackHanoi)stacks[3]).reportRejected() );
}  }
// 30  3  6 
10  0  14  23  39 
2  5  30  20  13  31  9 
4  30  11  15  36
// 30  3  6  10 
0  14  23  39  2 
5  30  20  13  31 
9  4  30  11  15 
36
// 0  2  4 
11  15  36
// 0  2  4 
11  15  36
// total rejected is 14