Patrón de diseño de grupo de objetos

El patrón de grupo de objetos es un patrón de diseño de creación de software que se utiliza en situaciones en las que el costo de inicializar una instancia de clase es muy alto. 

Básicamente, un grupo de objetos es un contenedor que contiene una cierta cantidad de objetos. Entonces, cuando se toma un objeto del grupo, no está disponible en el grupo hasta que se devuelve. 
Los objetos en el grupo tienen un ciclo de vida: 

  • Creación
  • Validación
  • Destruir.

Patrón de diseño de grupo de objetos de diagrama UML

  • Cliente: Esta es la clase que utiliza un objeto del tipo PooledObject.
  • ReuseablePool: la clase PooledObject es del tipo que es costoso o lento para crear instancias, o que tiene una disponibilidad limitada, por lo que debe mantenerse en el grupo de objetos.
  • ObjectPool: la clase Pool es la clase más importante en el patrón de diseño del grupo de objetos. ObjectPool mantiene una lista de objetos disponibles y una colección de objetos que ya se han solicitado del grupo.

Tomemos el ejemplo de las conexiones de base de datos. Obviamente, abrir demasiadas conexiones puede afectar el rendimiento por varias razones: 

  • Crear una conexión es una operación costosa.
  • Cuando hay demasiadas conexiones abiertas, lleva más tiempo crear una nueva y el servidor de la base de datos se sobrecarga.

Aquí, el conjunto de objetos administra las conexiones y proporciona una forma de reutilizarlas y compartirlas. También puede limitar el número máximo de objetos que se pueden crear. 

Java

// Java program to illustrate
// Object Pool Design Pattern
abstract class ObjectPool<T> {
    long deadTime;
 
    Hashtable<T, Long> lock, unlock;
 
    ObjectPool()
    {
        deadTime = 50000; // 50 seconds
        lock = new Hashtable<T, Long>();
        unlock = new Hashtable<T, Long>();
    }
 
    abstract T create();
 
    abstract boolean validate(T o);
 
    abstract void dead(T o);
 
    synchronized T takeOut()
    {
        long now = System.currentTimeMillis();
        T t;
        if (unlock.size() > 0) {
            Enumeration<T> e = unlock.keys();
            while (e.hasMoreElements()) {
                t = e.nextElement();
                if ((now - unlock.get(t)) > deadTime) {
                    // object has deadd
                    unlock.remove(t);
                    dead(t);
                    t = null;
                }
                else {
                    if (validate(t)) {
                        unlock.remove(t);
                        lock.put(t, now);
                        return (t);
                    }
                    else {
                        // object failed validation
                        unlock.remove(t);
                        dead(t);
                        t = null;
                    }
                }
            }
        }
        // no objects available, create a new one
        t = create();
        lock.put(t, now);
        return (t);
    }
    synchronized void takeIn(T t)
    {
        lock.remove(t);
        unlock.put(t, System.currentTimeMillis());
    }
}
 
// Three methods are abstract
// and therefore must be implemented by the subclass
 
class JDBCConnectionPool extends ObjectPool<Connection> {
    String dsn, usr, pwd;
 
    JDBCConnectionPool(String driver, String dsn, String usr, String pwd)
    {
        super();
        try {
            Class.forName(driver).newInstance();
        }
        catch (Exception e) {
            e.printStackTrace();
        }
        this.dsn = dsn;
        this.usr = usr;
        this.pwd = pwd;
    }
 
    Connection create()
    {
        try {
            return (DriverManager.getConnection(dsn, usr, pwd));
        }
        catch (SQLException e) {
            e.printStackTrace();
            return (null);
        }
    }
 
    void dead(Connection o)
    {
        try {
            ((Connection)o).close();
        }
        catch (SQLException e) {
            e.printStackTrace();
        }
    }
 
    boolean validate(Connection o)
    {
        try {
            return (!((Connection)o).isClosed());
        }
        catch (SQLException e) {
            e.printStackTrace();
            return (false);
        }
    }
}
 
class Main {
    public static void main(String args[])
    {
        // Create the ConnectionPool:
        JDBCConnectionPool pool = new JDBCConnectionPool(
            "org.hsqldb.jdbcDriver", "jdbc:hsqldb: //localhost/mydb",
            "sa", "password");
 
        // Get a connection:
        Connection con = pool.takeOut();
        // Return the connection:
        pool.takeIn(con);
    }
}

Ventajas

  • Ofrece un aumento significativo del rendimiento.
  • Administra las conexiones y proporciona una forma de reutilizarlas y compartirlas.
  • El patrón de grupo de objetos se usa cuando la tasa de inicialización de una instancia de la clase es alta.

Cuándo usar el patrón de diseño de grupo de objetos

  • Cuando tenemos un trabajo para asignar o desasignar muchos objetos
  • También, cuando sabemos que tenemos un número limitado de objetos que estarán en memoria al mismo tiempo.

Referencia: 
https://sourcemaking.com/design_patterns/object_pool
 

Publicación traducida automáticamente

Artículo escrito por saketkumr y traducido por Barcelona Geeks. The original can be accessed here. Licence: CCBY-SA

Deja una respuesta

Tu dirección de correo electrónico no será publicada. Los campos obligatorios están marcados con *