Serie Patrones de Diseño - Singleton
Bueno he decidido empezar un serie de articulos sobre los patrones de diseño y para empezar cual mejor que el Singleton.
El patrón de diseño singleton (patrón unitario) está diseñado para restringir la instanciación de una clase o valor de un tipo a un solo objeto. Resulta muy útil cuando por ejemplo se necesita un único objeto que coordina acciones en un sistema.
Para poder evitar que se creen instancias de la clase, debemos declarar el cosntructor como private. Asi declaramos una variable static que contendra la unica instacia de esa clase.
sealed class Singleton()
{
private Singleton()
{
/* ... codigo ... */
}
public static readonly Singleton Instance = new Singleton();
}
En el codigo anterior, definimos la clase como sealed, lo cual impide que de ella se deriven otras clases. Al tener el constructor definido como private, nadie podra querer instanciar tu clase.
Para usar ese objeto desde afuera, lo unico que hay que hacer es: Singleton s = Singleton.Instance;
En situacion multihilo, sin embargo, es posible que la varios hilos creen varias instacias del Objeto. Esto ocurre cuando los lenguajes no instancia a un nuevo objeto sino hasta que realiza la primera llamada al mismo (Tipo Visual Basic 6.0), esto lo hacen para obtener un mejor rendimiento, sin embargo, produce algunos incovenientes en aplicaciones multihilo.
Para solucionar este impase, debemos modificar el contructor de la clase, de la siguiente manera:
sealed class Singleton()
{
private Singleton()
{
if (Instance == null)
{
lock (typeof(Singleton))
{
if (Instance == null)
{
Instance = new Singleton();
}
}
}
/* ... codigo extra ... */
}
private static readonly Singleton Instance;
public Singleton getInstance()
{
return Instance;
}
}
Al momento de querer instanciar la clase, se verifica que no existe ninguna instancia previa, y luego se establece un bloqueo, esto para evitar que otros hilos quieran tambien crear una nueva instancia. Una vez dentro de la seccion critica, se vuelve a verificar que ningun otro hilo haya creado dicha instancia. De ser asi se crea una nueva.
La forma en que inicializa .Net los atributos marcados como readonly ya garantiza la seguridad en entornos multihebra.
Si no sincronizara su inicialización, el framework no podría garantizar que realmente son inicializados una única vez y, por tanto, no serían de verdad readonly.
Comment by pkito — September 14, 2005 @ 12:11 pm
Al marcar el atributo como readonly, la creación del objeto estará sincronizada y no hace falta montarse toda la historia de los lock.
Comment by pkito — September 20, 2005 @ 2:06 pm