Inicio > Programación > C++ : Patrón de diseño “singleton”

C++ : Patrón de diseño “singleton”

Lunes, 15 de septiembre de 2008 Dejar un comentario Ir a comentarios

Última edición: 17 Febrero 2011

Bueno … el nombrecito de este patrón de diseño se las trae un poco jeje, la verdad que a mi me recuerda un poco a eso de Bony & Tigretón, pero bueno eso no viene al caso xD. Intentando dar con una forma de hacer una clase accesible a diferentes partes de mi programa, he encontrado los llamados patrones de diseño “singleton”, técnica ampliamente utilizada en el mundo de la programación (en cualquier lenguaje) y que había escapado a mi conocimiento hasta el día de hoy. El concepto de esta técnica es sencillo, implementar una clase de la cual solo se pueda crear una instancia pero que pueda ser accedida desde cualquier parte de un programa. ¿Para que es útil esto? Pues para muchas cosas, a mi me ha servido para poder acceder a las distintas opciones de configuración introducidas por el usuario desde cualquier subsistema sin tener que andar pasando mensajes en una profunda jerarquía de clases. A continuación os daré más detalles sobre como implementarla.

Consideraciones

El uso de objetos globales te asegura que la instanciación es fácilmente accesible desde cualquier lugar, pero no te protege de la instanciación múltiple de objetos (Podrás crear una instancia local de la misma clase y esto seguramente te cause problemas). El patrón Singleton proporciona una elegante solución a este problema haciendo a la propia clase responsable del manejo de su única instancia.

Dicha instancia es un objeto ordinario de la clase, pero esta clase estará escrita de tal forma que solo se pueda crear una única instancia de la clase. De esta forma, tendrás la garantía de que ninguna otra instancia pueda ser creada. Además, conseguirás proporcionar un punto de acceso global a dicha instancia. Las clases Singleton ocultan la operación de creación de la instancia (constructor) detrás de una función miembro estática. Esta función miembro, normalmente llamada Instance(), devolverá un puntero a la única instancia.

Ejemplo

Veamos aquí una declaración típica de una clase Singleton:

class Singleton
{
   public:
      static Singleton* Instance();
   protected:
      Singleton();
      Singleton(const Singleton & ) ;
      Singleton &operator= (const Singleton & ) ;
   private:
      static Singleton* pinstance;
};

En vez de Singleton, puedes poner el nombre que desees a la clase, y declarar miembros adicionales.  Para asegurarse de que los usuarios no podrán crear instancias locales de la clase, el constructor de la clase, el operador de asignación y el constructor de copia serán declarados como protected. La clase también declara un puntero estático privado a su instancia pinstance. Cuando la función Instance() es llamada por primera vez, esta crea la instancia, asignando la dirección a la misma y devolviendo dicha dirección. En las subsiguientes llamadas a la función, solamente se devolverá esta dirección. La implementación será algo como:

Singleton* Singleton::pinstance = 0;// Inicializar el puntero
Singleton* Singleton::Instance ()
{
  if (pinstance == 0)  // ¿Es la primera llamada?
  {
    pinstance = new Singleton; // Creamos la instancia
  }
  return pinstance; // Retornamos la dirección de la instancia
}
Singleton::Singleton()
{
  //... Realizar inicializaciones necesarias de la instancia
}

Los usuarios solo podrán acceder a la instancia por medio de la función Instance(). Cualquier intento de crear una instancia que no sea a través de esta función fallará ya que el constructor de la clase está protegido. Note que este diseño es a prueba de balas, las siguientes llamadas a Instance() devuelven un puntero a la misma instancia:

Singleton *p1 = Singleton::Instance();
Singleton *p2 = p1->Instance();
Singleton &ref = * Singleton::Instance();

Aunque este ejemplo use una única instancia, con alguna que otra modificación a la función Instance(), este patrón permite un número variable de instancias. Por ejemplo, podríamos diseñar una clase que permitiese trabajar con cinco instancias.

Por último, y es algo que no había tenido en cuenta en un principio, debemos ocuparnos de la eliminación de la instancia que creemos. En este enlace explican como hacerlo.

Fuentes:

GD Star Rating
loading...
C++ : Patrón de diseño "singleton", 8.6 out of 10 based on 9 ratings
Share
Categories: Programación Tags: ,
  1. Martes, 16 de septiembre de 2008 a las 10:58 | #1
    GD Star Rating
    loading...

    Hace tiempo que vengo oyendo hablar de singleton, pero hasta ahora no me había fijado demasiado. Es una lástima que esto no pueda utilizarse con java.

  2. Martes, 30 de septiembre de 2008 a las 20:59 | #2
    GD Star Rating
    loading...

    Iba visto mucho lo del singleton, como por ejemplo el API de Ogre, yo tengo un singleton implementado (algo parecido) sin saber que era : http://blogricardo.wordpress.com/2008/07/22/como-hacer-juegos-profesionales-linux-ogre-physx-2a-parte/
    Viendo lo útil que es esto debería pillarme patrones como libre elección ?

  3. programatta
    Martes, 17 de febrero de 2009 a las 15:17 | #3
    GD Star Rating
    loading...

    Elvenbyte si que se puede realizar estos patrones en Java :-)

  4. Alfredo Pons
    Viernes, 14 de mayo de 2010 a las 10:51 | #4
    GD Star Rating
    loading...

    Si, si que se puede en Java y en muchos otros lenguajes:
    http://es.wikipedia.org/wiki/Singleton

  5. Martes, 22 de febrero de 2011 a las 21:43 | #5
    GD Star Rating
    loading...

    @elvenbyte
    ¿¿Cómo que no se puede?? estamos grave compañero y grave es de muerte….

  6. Fabian
    Sábado, 12 de marzo de 2011 a las 03:38 | #6
    GD Star Rating
    loading...

    @elvenbyte
    claro que si se puede implementar en java

  7. Ernesto Alfonso
    Martes, 2 de abril de 2013 a las 17:31 | #7
    GD Star Rating
    loading...

    Ha sido útil, pero cuando quiero trabajar herencia (en java también se puede) me da bateos:
    Error 2 error C2371: ‘a_instance’ : nueva definición; tipos básicos distintos C:\Users\3dserver\Desktop\MataheuristicTester\MataheuristicTester\TabuStore.cpp 3

  1. Sin trackbacks aún.