java

En un articulo anterior habíamos resaltado la importancia de los patrones de diseño en la programación y el porque deberíamos utilizarlos en nuestros proyectos, en este articulo vamos a realizar dos formas de implementar el famoso patrón de diseño Singleton en Java.

Singleton basado en clases

El enfoque más popular en la utilización de los patrones de diseño es implementar un Singleton creando una clase regular y asegurándose de que tenga:

  • Un constructor privado
  • Un campo estático que contiene su única instancia
  • Un método de fábrica estático para obtener la instancia

También agregaremos una propiedad de información, esto con el fin de usarlo posteriormente. Por lo tanto, nuestra implementación se verá así:

public final class ClassSingleton {
 
    private static ClassSingleton INSTANCE;
    private String info = "Initial info class";
     
    private ClassSingleton() {        
    }
    // Forma de instanciación
    public static ClassSingleton getInstance() {
        if(INSTANCE == null) {
            INSTANCE = new ClassSingleton();
        }
         
        return INSTANCE;
    }
 
    // getters y setters de  la clase
}

Si bien este es un enfoque común, es importante tener en cuenta que puede ser problemático en escenarios de subprocesamiento múltiple, que es la razón principal para usar Singletons.

En pocas palabras, puede dar como resultado más de una instancia, rompiendo el principio básico del patrón. Aunque definitivamente existen soluciones de bloqueo para este problema, nuestro próximo enfoque resuelve estos problemas a nivel de raíz.

Enum Singleton

Otro enfoque muy interesante es usar enumeraciones en las que también podemos aplicar patrones de diseño, de tal forma que nuestra implementación quede de la siguiente manera:

public enum EnumSingleton {
     
    INSTANCE("Información Inicial de la clase"); 
  
    private String info;
  
    private EnumSingleton(String info) {
        this.info = info;
    }
    // Metodo de instanciación del Enum
    public EnumSingleton getInstance() {
        return INSTANCE;
    }
     
    // getters y setters de la clase
}

Este enfoque tiene la serialización y la seguridad de subprocesos garantizados por la implementación de enum, que asegura internamente que solo está disponible la instancia única, corrigiendo los problemas señalados en la implementación basada en clases.

Forma de uso

Para usar nuestro ClassSingleton, simplemente necesitamos obtener la instancia estáticamente:

ClassSingleton classSingleton1 = ClassSingleton.getInstance();
 
System.out.println(classSingleton1.getInfo()); //Información inicial de la clase
 
ClassSingleton classSingleton2 = ClassSingleton.getInstance();
classSingleton2.setInfo("Información de la nueva Clase");
 
System.out.println(classSingleton1.getInfo()); //Información de la nueva Clase1
System.out.println(classSingleton2.getInfo()); //Información de la nueva Clase2

En cuanto a EnumSingleton, podemos usarlo como cualquier otro Java Enum:

EnumSingleton enumSingleton1 = EnumSingleton.INSTANCE.getInstance();
 
System.out.println(enumSingleton1.getInfo()); ////Información inicial de la clase
 
EnumSingleton enumSingleton2 = EnumSingleton.INSTANCE.getInstance();
enumSingleton2.setInfo("Nueva información de enum");
 
System.out.println(enumSingleton1.getInfo()); // Nueva información de enum1
System.out.println(enumSingleton2.getInfo()); // Nueva información de enum2

Conclusión

En este articulo nos enfocamos en cómo implementar el patrón de Singleton utilizando solo Java, y cómo asegurarnos de que sea consistente y cómo hacer uso de estas implementaciones en nuestros proyectos.

 

Dejar respuesta

Please enter your comment!
Please enter your name here