Patrón de diseño Singleton en Java

Este es uno de los patrones más conocidos y es quizás el primero que se nos viene a la cabeza cuando nos preguntas sobre patrones de diseño en Java.

El objetivo es que una clase sólo tenga una instancia viva y garantizar que esto suceda.

El patrón de diseño Singleton tiene muchas formas de implementarse pero veremos aqui la base de sus implementación que consiste en:

  • Dejar el constructor de la clase privado evitando que se pueda usar new
  • Crear una variable static en la clase que guardará la instancia de dicha clase.
  • Crear un método público que nos devolverá siempre la misma instancia de la clase que hemos guardado en la variable.

Qué es un patrón de diseño Singleton

Normalmente cuando creamos un objeto en Java usamos el keyword new.

Esto lo que hace es crear una nuevo Objeto cada vez que se lo requiera. SIn embargo, existen ocasiones en las que no deseamos crear un nuevo objeto, al contrario, deseamos ‘compartir’ el objeto.

EL patrón de diseño singleton nos asegura que solo un objeto sea creado y que solo exista una sola instancia del objeto para la clase.

Cada vez que necesitemos el objeto obtendremos la misma instancia.

Cómo se implementa el patrón Singleton

Hay varias maneras para implementar el patrón Singleton. Veamos cada una.

Implementación Básica Singleton Pattern

Esta es la forma básica que tendría una clase Singleton. En donde hacemos privado el constructor para evitar su creación con new y definimos un método que nos devuelve siempre la misma instancia.

Java Singleton Pattern

 1
 2
 3
 4
 5
 6
 7
 8
 9
10
11
12
13
package patterns;

public class SingletonExample {

    private static SingletonExample instance = new SingletonExample();

    private SingletonExample() {
    }

    static SingletonExample getInstance() {
        return instance;
    }
}

Implementación Singleton Perezosa (Lazy initialization)

Bien, si vemos la implementación previa podemos pensar que estamos creando una instancia siempre, instance = new SingletonExample(), aunque no sea requerida. Podemos pensar en otra implementación en la que realmente se cree el objeto cuando se lo requiera.

Para esto la variable permanece nula y la inicializamos la primera vez que se invoque el método getInstance() .

Para prevenir que dos hilos ingresen en simultáneo la primera vez sincronizamos la creación de la instancia.

 1
 2
 3
 4
 5
 6
 7
 8
 9
10
11
12
13
14
15
16
17
18
19
20
package patterns;

public class SingletonExample2 {

    private static SingletonExample2 instance;

    private SingletonExample2() {
    }

    static SingletonExample2 getInstance() {
        if (instance == null) {
            synchronized (SingletonExample2.class) {
                if (instance == null) {
                    instance = new SingletonExample2();
                }
            }
        }
        return instance;
    }
}

En este artículo viste las dos formas más simples de crear un Singleton que no pueden faltar cuando te pregunten al respecto.

Puedes descargar este código en github o en gitlab