Singleton Revisited…

El día de hoy estuve platicando con uno de mis lectores del blog y me preguntó para que sirve eso de Singleton que puse en uno de mis anteriores posts

Bueno, para aclarar este punto; voy a meterme a explicar brevemente para que sirve. Singleton permite que una clase tenga una y solo una instancia y nos provee de un punto de acceso global a ella. Esto quiere decir que cada instancia de una clase que hagamos será la misma.

Este es uno de los patrones de diseño más sencillos que existen y más utilizados.

Revisemos esta estructura de código para ver que es lo que nos dá:

1 using System;
2
3 class Singleton
4 {
5 private static Singleton instance;
6
7 protected Singleton() {}
8
9 public static Singleton Instance()
10 {
11 if( instance == null )
12 instance = new Singleton();
13
14 return instance;
15 }
16 }
17
18 public class Client
19 {
20 public static void Main()
21 {
22 Singleton s1 = Singleton.Instance();
23 Singleton s2 = Singleton.Instance();
24
25 if( s1 == s2 )
26 Console.WriteLine( «Somos la misma instancia :)» );
27 }
28 }
  • Linea 3 a 16 – declaramos nuestra clase de Singleton.
  • Linea 22 – declaramos s1 como una instancia de Singleton
  • Linea 23 – declaramos s2 como una instancia de Singleton
  • Hacemos la comparación y nos da un resultado que la instancia es la misma.

¿Por qué no se hace el New dentro de la línea 22?
Checate bien como esta declarado el constructor de SingletonProtected… eso no nos permite hacer un New sobre nuestro Singleton… El New se hace dentro de la sección donde queremos obtener la instancia del objeto (línea 11 y 12)

Ya viendo este código, hace un poco de más sentido… Veamos un ejemplo de la vida real:

Supongamos que tenemos 5 servidores y deseamos hacer el balanceo de cargas (redireccionamiento) vía un objeto/función provista por nuestra propia aplicación. Lo que voy a hacer es crear una clase que se llama LoadBalancer la cual, nos dará un servidor al azar para hacer este redireccionamiento.

Veamos el código:

1 using System;
2 using System.Collections;
3 using System.Threading;
4
5 class LoadBalancer
6 {
7 private static LoadBalancer balancer;
8 private ArrayList servers = new ArrayList();
9 private Random random = new Random();
10
11 protected LoadBalancer()
12 {
13 servers.Add( «ServerI» );
14 servers.Add( «ServerII» );
15 servers.Add( «ServerIII» );
16 servers.Add( «ServerIV» );
17 servers.Add( «ServerV» );
18 }
19
20 public static LoadBalancer GetLoadBalancer()
21 {
22 if( balancer == null )
23 {
24 Mutex mutex = new Mutex();
25 mutex.WaitOne();
26
27 if( balancer == null )
28 balancer = new LoadBalancer();
29
30 mutex.Close();
31 }
32 return balancer;
33 }
34
35 public string Server
36 {
37 get
38 {
39 int r = random.Next( servers.Count );
40 return servers[ r ].ToString();
41 }
42 }
43 }
44
45 public class SingletonApp
46 {
47 public static void Main( string[] args )
48 {
49 LoadBalancer b1 = LoadBalancer.GetLoadBalancer();
50 LoadBalancer b2 = LoadBalancer.GetLoadBalancer();
51 LoadBalancer b3 = LoadBalancer.GetLoadBalancer();
52 LoadBalancer b4 = LoadBalancer.GetLoadBalancer();
53
54 Console.WriteLine( b1.Server );
55 Console.WriteLine( b2.Server );
56 Console.WriteLine( b3.Server );
57 Console.WriteLine( b4.Server );
58 }
59 }

Aquí la idea es la siguiente:

  • Declaramos nuestra clase LoadBalancer junto con nuestro constructor (Líneas 5 a 20)
  • Generamos un Mutex para soporte a multi-threading (DoubleChecking) (Línea 24-25)
  • Mandas a llamar la instancia para que te regrese un servidor (Línea 49 a 52)
  • Como esta instancia es la misma, sabe cual fué el último servidor que asignó (Línea 39 y 40)
  • Mostramos en la consola cuales son los servidores que nos dió nuestro LoadBalancer (Línea 54 a 57)

¿Alguien tiene algún otro ejemplo de implementación de Singleton en una aplicación de la vida real?

Cheers!

(Referencias: MartinFowlerBliki)


Comentarios

Deja una respuesta