Thursday, September 11, 2014

Object Pool Design Pattern


Definition

Object Pool Design Pattern is a creational Design Pattern that is used to reuse the resources as a pool of objects. Like Prototype Pattern helping in improving the performance by cloning the objects, the Object Pool pattern offers a mechanism to reuse objects that are time and resource expensive to create.

 The pattern will create a pool of required objects and serve the client on request based. Only if  all the objects in the pool have allocated to client request, new object is created in the pool and serve the new client. After serving the client's responsible to release the object and put to the pool back. This could large be seen in creating Database Connections.

Intention

        Creates a pool to keep time and resource expensive objects and share them among the clients requests without creating new objects per each request.


Component

Client - uses an instance of type Reusable.
Reusable Object - Wraps the limited resource, will be shared by several clients for a limited amount of time.
Object Pool - manage the reusable objects for use by Clients, creating and managing a pool of objects.











Code


Object Pool

abstract class ObjectPool<T> {             // This is a Generic class for any type assigned to <T>

    private long expirationTime;           // An object in the pool will be active
                                           //for time assigned to this variable.

    private Hashtable<T, Long> locked, unlocked;

    public ObjectPool() {
        expirationTime = 30000; // 30 seconds
        locked = new Hashtable<T, Long>();   // Table of allocated objects to the client.           
        unlocked = new Hashtable<T, Long>(); // Table of unallocated objects free to use to the client
    }

    protected abstract T create();

    public abstract boolean validate(T o);

    public abstract void expire(T o);

    public synchronized T getConnectionFromPool() {     
        long now = System.currentTimeMillis();
        T t;
        if (unlocked.size() > 0) {
            Enumeration<T> e = unlocked.keys();
            while (e.hasMoreElements()) {
                t = e.nextElement();
                if ((now - unlocked.get(t)) > expirationTime) {
                    // object has expired
                    unlocked.remove(t);
                    expire(t);
                    t = null;
                } else {
                    if (validate(t)) {
                        unlocked.remove(t);
                        locked.put(t, now);
                        return (t);
                    } else {
                        // object failed validation
                        unlocked.remove(t);
                        expire(t);
                        t = null;
                    }
                }
            }
        }
        // no objects available, create a new one
        t = create();
        locked.put(t, now);
        return (t);
    }

    public synchronized void putConnectionBackToPool(T t) {     
        locked.remove(t);
        unlocked.put(t, System.currentTimeMillis());
    }
}

Object Pool Implementation (JDBCPool)

public class JDBCPool extends ObjectPool<Connection> {

   
     private String connectionURL, userName, password;

      public JDBCPool(String driver, String connectionURL, String userName, String password) {
        super();
        try {
          Class.forName(driver).newInstance();
        } catch (Exception e) {
          e.printStackTrace();
        }
        this.connectionURL = connectionURL;
        this.userName = userName;
        this.password = password;
      }
   
    @Override
    protected Connection create() {
       

        try {
          return (DriverManager.getConnection(connectionURL, userName, password));
        } catch (SQLException e) {
          e.printStackTrace();
          return (null);
        }
    }

    @Override
    public boolean validate(Connection o) {

        try {
          return (!((Connection) o).isClosed());
        } catch (SQLException e) {
          e.printStackTrace();
          return (false);
        }
     
    }

    @Override
    public void expire(Connection o) {
        try {
              ((Connection) o).close();
            } catch (SQLException e) {
              e.printStackTrace();
            }
       
    }

}

Client

public class Client {

    public static void main(String[] args) {
       
        // Creates the ConnectionPool:
        JDBCPool pool = new JDBCPool(
          "driver name", "driver URL",  //You have to replace these values
          "userName", "password");     // According to you db connection and db

        // Get a connection:
        Connection con = pool.getConnectionFromPool();

        // Performs DB actions with the connection
     
        // Returns the connection to the pool
        pool.putConnectionBackToPool(con);
   
      }
       
}




No comments: