jueves, 31 de mayo de 2007

El Patrón Singleton con C#

Uno de los patrones de diseño sin lugar a dudas más utilizado y conocido, es el patrón Singleton. De forma resumida, un singleton en una clase que únicamente permite que exista simultáneamente una única instancia de si misma y que ofrece un punto de acceso común a ella.
Este patrón nos puede ayudar en situaciones en las que queramos que haya únicamente una única instancia de una clase, por ejemplo para tener un acceso centralizado a un sistema de log o un sistema de caché, de forma que desde cualquier punto de la aplicación en el que queramos utilizar estos recursos, podamos garantizar que accedamos siempre a la misma instancia.
El código necesario para poder disponer de un singleton es realmente sencillo, son básicamente 2 líneas, que podremos ampliar con el comportamiento específico que queramos darle.


sealed class Singleton
{
private Singleton() {}
public static readonly Singleton Instance = new Singleton();
}


Para utilizar el código, podríamos usar desde cualquier punto Singleton.Instance y accederíamos siempre a la misma instancia.
Entrando un poco más al detalle del código utilizado, merece la pena explicar un par de cosas referentes a cómo se crea la instancia y cómo se evitan posibles problemas que podrían provocarse, sobretodo en entornos multihilo.
Lo primero de todo es destacar como el constructor de la clase está marcado como “private”, lo cual hace imposible crear instancias de la clase y nos obliga a acceder a la única posible instancia a través de la propiedad Instance. Con el mismo fin la clase está marcada como “sealed”, por lo que nos garantizamos de que nadie va a poder heredar de esta clase y crear múltiples instancias de nuestro singleton.
En cuanto a la instancia de la clase, está marcada como “public”, “readonly” y “static”, lo cual hace que se pueda acceder a ella desde cualquier otra parte, que no sea modificable y que se cree la primera vez que se acceda a ella, como veremos más adelante.
Hay un par de cuestiones típicas que suelen afectar a otras implementaciones de este patrón en otros lenguajes, una es la inicialización perezosa y la segunda los posibles problemas con el uso de múltiples hilos. La inicialización perezosa se refiere a la conveniencia por eficiencia, de no crear la instancia hasta el momento en que se acceda por primera vez a la instancia. En otros lenguajes esto se realiza mediante un “if” en un método “getInstance”, que comprueba si la instancia ha sido ya creada o no, de forma que se crea la primera vez que se llama al método. En situaciones multihilo esto puede provocar que varios hilos entre en el “if” a la vez, creando varias instancias. Para solventar este posible problema se suele utilizar una solución basada en un “Double-Check”, en la cual, lo primero que hace el método “getInstance” es comprobar si la instancia ha sido creada y en caso contrario entra en una “sección crítica”, en la cual se vuelve a realizar la comprobación y si sigue sin estar creada, se crea. De esta forma si dos hilos entran en el primer “if”, al llegar a la sección crítica sus accesos se serializarían, produciendo que el primero de ellos crease la instancia y al entrar el segundo, la comprobación de si existe la instancia fuera positiva. A continuación puede verse el código correspondiente a este funcionamiento en C#, aunque no es necesario utilizarlo, ya que el código mostrado anteriormente tiene la misma funcionalidad como veremos a continuación.

class Singleton
{
public static Singleton Instance()
{
if (_instance == null)
{
lock (typeof(Singleton))
{
if (_instance == null)
{
_instance = new Singleton();
}
}
}
return _instance;
}

protected Singleton() {}
private static volatile Singleton _instance = null;
}

2 comentarios:

Unknown dijo...

El código más simple que he encontrado para el Singleton

Felicitaciones

sozo dijo...

en singleton trataria de que de una clase solo se pueda instanciar un objeto?
vaya vi que existen muchas mas palabras reservadas,
Una ayuda porfavor ,sabes de donde puedo descargarme el ebook "c# al descubierto de joshep mayo" ?
lei en internet y es buenisimo ,creo q es el mejor ,muy completo
si lo tienes puedes pasarmelo?
busque en ares,emule y en la web y no hay ,solo existe para la venta
mi correo es:
syd.sozo@gmail.com
chau