Singleton - manu9/patterns GitHub Wiki

La idea del patrón Singleton es proveer un mecanismo para limitar el número de instancias de una clase. Por lo tanto el mismo objeto es siempre compartido por distintas partes del código.

Por eso a veces es importante tener sólo una instancia para una clase. Por ejemplo, en un sistema debe haber sólo un gestor de ventanas (o sólo un sistema de archivos o sólo una clase que proporcione conexión a base de datos), por lo tanto cuando la aplicación requiere que solo exista una instancia de un determinado objeto.

El patrón singleton es uno de los patrones de diseño más simples: implica sólo una clase que es responsable de instanciarse, para asegurarse de que no crea más de una instancia; Al mismo tiempo que proporciona un punto de acceso global a esa instancia. En este caso, la misma instancia se puede utilizar en todas partes, siendo imposible invocar directamente al constructor cada vez.

Dicho de otra manera, esta patrón busca garantizar que una clase sólo cree un objeto y proporcione un punto de acceso global a ella.

Este patrón tiene dos reglas:

- El constructor debe ser privado para que no se pueda llamar y por lo tanto, no se 
  puedan crear instancias.
- Crear una instancia de la clase y devolverla mediante un método estático.

Representacion Standar UML

Singleton UML

Donde es Aconsejable este Patrón

  • Clases que se encarguen de escribir información del sistema, clases de LOG
  • Clases de almacenamiento de Cache
  • Clases de load-balancing (balanceador o equilibrador de carga)
  • Clases de configuraciones o que se encarguen del acceso a configuraciones.
  • Clases de conexión a base de datos

Revisando algunos articulos interesantes como estos:

La mejor forma de crear un singleton son las siguientes, siendo la mejor la Enum.

public class MySingleton {
    private static MySingleton INSTANCIA = null;

    private MySingleton(){}

    public static MySingleton getInstancia(){
        if(INSTANCIA == null){
            synchronized (MySingleton.class){
                if(INSTANCIA == null){
                    INSTANCIA = new MySingleton;
                }
            }
        }
        return INSTANCIA;
    }
}
public class MySingleton {
    private MySingleton() {}

    private static class SingletonUisngInner {
        private static MySingleton mySingleton = new MySingleton();
    }

    public static MySingleton getInstance() {
        return SingletonUisngInner.mySingleton;
    }

    public static String saludar(){
        return "hola";
    }
}

// Ejemplo de implementación
// Esto me gusta porque podemos llamar a los metodos inmediatamente.
public static void main(String[] args) {
    System.out.println(MySingleton.getInstance().saludar());
}

con enum:

public enum  EnumSingleton{
    INSTANCE;

    public String saludar(){
        return "Hola!";    
    }
}

// Ejemplo de implementación
// luego obtenemos la instancia, que será única y siempre la misma
public static void main(String[] args) {
    EnumSingleton enumSingleton = EnumSingleton.INSTANCE;
    System.out.println(enumSingleton.saludar());
}

// Output: Hola!