lunes, 2 de enero de 2012

Patrones de diseño: Singleton

Estoy intentando ampliar mis conocimientos acerca de los patrones de diseño. Es un tema muy interesante, y además ayuda a profundizar y mejorar la comprensión sobre ciertos conceptos avanzados del diseño orientado a objetos.
He decidido empezar con el patrón llamado Singleton por su sencillez y porque es uno de los más conozco y he utilizado en ocasiones. Este patrón permite garantizar que no se pueda instanciar más de un objeto de una determinada clase. A continuación se puede ver el código de una clase que implementa el patrón Singleton de modo seguro en entornos multitarea mediante el uso de bloqueos.

    public sealed class Singleton
    {
        static Singleton instance = null;
        static readonly object padlock = new object(); //Objeto compartido para bloquear el acceso simultáneo

        public static String datos;
        Singleton()
        {
        }

        public static Singleton getInstance()
        {
            lock (padlock)
            {
                if (instance == null)
                {
                    instance = new Singleton();
                    datos = "Dato inicial";
                }
                return instance;
            }
        }
    }
Podemos ver con un ejemplo como se comporta la clase Singleton cuando se invoca varias veces. Se observa que en la variable datos de la clase se tiene el dato introducido inicialmente, y en ningún caso varía cuando se intenta obtener una nueva instancia de la clase porque la instancia obtenida es siempre la misma.

using System;
using System.Threading;

namespace ConsoleApplication1
{
    class Program
    {
        static void Main(string[] args)
        {
            Singleton.getInstance();
            Console.WriteLine("Dato inicial: " + Singleton.datos);
            Singleton.datos = "Dato cualquiera";

            for (int i = 1; i <= 50; i++)
            {
                Thread t1 = new Thread(ThreadMain);
                t1.Name = "Hilo_" + i.ToString();
                t1.Start();
            }

            Console.ReadLine();
        }

        static void ThreadMain()
        {
            //
            Singleton.getInstance();
            Console.WriteLine(Thread.CurrentThread.Name + "  " + "datos: " + Singleton.datos);
        }
    }

A continuación se puede ver el resultado de la ejecución del código de prueba.


Versión 2:

public sealed class MySingleton
{
    private static MySingleTon _instance;

    private MySingleton()
    {
    }

    public static MySingleton Instance()
    {
        if(_instance == null)
        {
            _instance = new MySingleton();
        }
        return _instance;
    }
}

static void Main(string[] args)
{
    MySingleton single1 = MySingleton.Instance();
    MySingleton single2 = MySingleton.Instance();

    if(single1 == single2)
    {
        Console.WriteLine("These two objects are the same.");
    }
}

No hay comentarios:

Publicar un comentario