The PoolManager using Proxy : Proxy Pattern « Design Pattern « Java Tutorial






import java.util.ArrayList;

class PoolItem {
  boolean inUse = false;

  Object item;

  PoolItem(Object item) {
    this.item = item;
  }
}

class ReleasableReference { // Used to build the proxy
  private PoolItem reference;

  private boolean released = false;

  public ReleasableReference(PoolItem reference) {
    this.reference = reference;
  }

  public Object getReference() {
    if (released)
      throw new RuntimeException("Tried to use reference after it was released");
    return reference.item;
  }

  public void release() {
    released = true;
    reference.inUse = false;
  }
}

class PoolManager {

  private ArrayList<PoolItem> items = new ArrayList<PoolItem>();

  public void add(Object item) {
    items.add(new PoolItem(item));
  }

  public static class EmptyPoolItem {
  }

  public ReleasableReference get() {
    for (int i = 0; i < items.size(); i++) {
      PoolItem pitem = (PoolItem) items.get(i);
      if (pitem.inUse == false) {
        pitem.inUse = true;
        return new ReleasableReference(pitem);
      }
    }
    return null;
  }
}

interface Connection {

  Object get();

  void set(Object x);

  void release();

}

class ConnectionImplementation implements Connection {

  public Object get() {
    return null;
  }

  public void set(Object s) {
  }

  public void release() {
  }

}

class ConnectionPool { // A singleton
  private static PoolManager pool = new PoolManager();

  private ConnectionPool() {
  }

  public static void addConnections(int number) {
    for (int i = 0; i < number; i++)
      pool.add(new ConnectionImplementation());
  }

  public static Connection getConnection() {
    ReleasableReference rr = (ReleasableReference) pool.get();
    if (rr == null)
      return null;
    return new ConnectionProxy(rr);
  }
}

class ConnectionProxy implements Connection {

  private ReleasableReference implementation;

  public ConnectionProxy(ReleasableReference rr) {
    implementation = rr;
  }

  public Object get() {
    return ((Connection) implementation.getReference()).get();
  }

  public void set(Object x) {
    ((Connection) implementation.getReference()).set(x);
  }

  public void release() {
    implementation.release();
  }
}

public class ConnectionPoolProxyDemo {
  public static void main(String args[]) {
    try {
      ConnectionPool.addConnections(5);
      Connection c = ConnectionPool.getConnection();
      c.set(new Object());
      c.get();

      c.release();
      c = ConnectionPool.getConnection();
      c.set(new Object());
      c.get();
      c.release();
      c.get();
    } catch (Exception e) {
      System.out.println(e.getMessage());
    }
  }
}








34.16.Proxy Pattern
34.16.1.Proxy: fronting for another object
34.16.2.The PoolManager using Proxy
34.16.3.Dynamic Proxies