Singleton
El patrón de diseño singleton (instancia
única) está diseñado para restringir la creación de objetos pertenecientes a
una clase o el valor de
un tipo a un único objeto.
Su intención consiste en garantizar que una
clase sólo tenga una instancia y proporcionar un punto de acceso global a ella.
El patrón singleton se implementa creando en nuestra clase un método
que crea una instancia del objeto sólo si todavía no existe alguna. Para
asegurar que la clase no puede ser instanciada nuevamente se regula el alcance
del constructor (con atributos como protegido o privado).
La instrumentación del patrón puede ser delicada
en programas con múltiples hilos de ejecución. Si dos hilos de ejecución intentan
crear la instancia al mismo tiempo y esta no existe todavía, sólo uno de ellos
debe lograr crear el objeto. La solución clásica para este problema es utilizar exclusión
mutua en el método de creación de la clase que implementa el patrón.
Las situaciones más habituales de aplicación de
este patrón son aquellas en las que dicha clase controla el acceso a un recurso
físico único (como puede ser el ratón o un archivo abierto en modo exclusivo) o
cuando cierto tipo de datos debe estar disponible para todos los demás objetos
de la aplicación.
El patrón singleton provee una única instancia global gracias a que:
La propia clase es responsable de crear la única
instancia.
Permite el acceso global a dicha instancia
mediante un método de clase.
Declara el constructor de clase como privado
para que no sea instanciable directamente.
Implementacion
Java
Una implementación correcta en el lenguaje de programación Java para programas multi-hilo es la solución conocida como "inicialización bajo demanda" sugerida por Bill Pugh:
public class Singleton { private static Singleton INSTANCE = new Singleton(); // El constructor privado no permite que se genere un constructor por defecto // (con mismo modificador de acceso que la definición de la clase) private Singleton() {} public static Singleton getInstance() { return INSTANCE; } }
Un ejemplo correcto de inicialización diferida. Se deja para comentar un error común en Java al no tener en cuenta la sincronización de métodos.
public class Singleton { private static Singleton INSTANCE = null; // Private constructor suppresses private Singleton() {} // creador sincronizado para protegerse de posibles problemas multi-hilo // otra prueba para evitar instanciación múltiple private synchronized static void createInstance() { if (INSTANCE == null) { INSTANCE = new Singleton(); } } public static Singleton getInstance() { if (INSTANCE == null) createInstance(); return INSTANCE; } }
Para asegurar que se cumpla el requerimiento de
"única instancia" del singleton; la clase debería producir un objeto
no clonable:
//Así se podría clonar el objeto y no tendria unicidad. SingletonObjectDemo clonedObject = (SingletonObjectDemo) obj.clone();
Entonces, se debería impedir la clonacion
sobreescribiendo el método "clone" de la siguiente manera:
//El método "clone" es sobreescrito por el siguiente que arroja una excepción: public Object clone() throws CloneNotSupportedException { throw new CloneNotSupportedException(); }
No hay comentarios:
Publicar un comentario