Contenido

El patrón Singleton

Para qué sirve

Permite tener una única instancia de un objeto en toda la aplicación

Patrones de diseño

Cómo implementarlo en Java

Necesitamos ocultar el constructor, haciéndolo privado. Para poder obtener el objeto, necesitaremos un método estático que lo construya si es necesario o lo devuelva si ya estaba construido. Hay varias implementaciones, por ejemplo:

 1
 2
 3
 4
 5
 6
 7
 8
 9
10
11
12
public class Example {
    private static Example instance = null;

    private Example() {
    }

    public static Example getInstance() {
        if (instance == null)
            instance = new Example();
        return instance;
    }
}

¿Cuándo utilizarlo?

Ésta es la más fácil: NUNCA.

Vale, pero… para algo servirá… NO

¿El patrón singleton es el diablo?

¿No hay ninguna excepción?

Tan solo se me han ocurrido dos casos en los que es posible que nos ayude este patrón. En cualquier otro caso es muy probable que traiga más problemas que soluciones. La primera de ellas es el sistema de log. La segunda, el sistema de configuración.

Tanto la configuración como el sistema de log son elementos de nuestra aplicación que se espera que no cambien demasiado a menudo, y deben ser accesibles desde todos los puntos de nuestra aplicación.

Cosas que deben tenerse en cuenta

Si por una casualidad decidimos implementar un singleton o bien nos encontramos con un singleton, recomiendo siempre crear un método reset, que permita establecer el estado inicial del singleton. Esto permitirá poder hacer pruebas, ya que podemos asumir que, por definición, no se pueden hacer pruebas de un singleton.

Ahora bien: si vemos que vamos a necesitar más de un singleton (por ejemplo, necesitamos el sistema de log y la configuración), mi consejo es implementar ambos como objetos normales y crear un único singleton que permita crear y obtener la única instancia de ambos. A veces llaman a este método “patrón toolbox

De esta manera podemos probar cada objeto por separado y tenemos un objeto que tan sólo construirá el resto. Aún así, insisto en que no es una práctica recomendada.

De hecho, como regla general, no es recomendable utilizar clases estáticas, ya que suelen ser más complejas de probar y son más difíciles de “transformar”. Me explico: durante la vida del software, a menudo que van apareciendo nuevos requisitos, las cosas se transforman: los literales se transforman en constantes; las constantes, en variables; las variables en sentencias; las sentencias, en métodos; los métodos, en clases. Si tenemos un método estático, sólo puede derivar en una clase estática, lo que resulta imposible de probar y, además, imposible de paralelizar.

Imaginaos que tenemos una clase estática con una funcionalidad determinada y queremos usarla desde un servidor web. Bien: simplemente no podemos. Existen dos opciones:

  • La clase tiene estado: dos accesos concurrentes alterarán el estado obteniendo resultados inciertos.
  • La clase no tiene estado: ¿Qué más nos da implementarla como dinámica? Quizá en el futuro sí necesitemos estado.

Resumiendo

Así que ya sabéis: evitad el uso de static en la medida de lo posible.

Referencias

Aunque me las pasó Julia después de haber escrito este artículo, creo que pueden resultar muy útiles: