Mostrando entradas con la etiqueta Pattern Design. Mostrar todas las entradas
Mostrando entradas con la etiqueta Pattern Design. Mostrar todas las entradas

sábado, agosto 22, 2009

C++ Singleton Pattern (y II)

Y ya que estamos, os dejo la segunda parte que también había escrito hace bastante tiempo :)

Vamos a continuar con el patrón de diseño Singleton que habíamos comenzado en un post anterior. Intentaremos añadir alguna que otra mejora. Vayamos poquito a poquito:

Un primer cambio que podríamos realizar sería el de retornar una referencia en lugar de un puntero en el método getInstance(); de este modo evitaríamos que el usuario que obtiene una referencia del objeto intentase aplicarle el operador delete. El prototipo del nuevo método podría ser algo parecido a lo siguiente:

static singletonPattern & getInstance();


Ahora podríamos pensar en que ocurre cuando se destruye el singleton.Realmente no se trata un memory leak tradicional sino un resource leak. El singleton podría haber adquirido diversos recursos del sistema operativo como un socket,un semáforo,...... Con el objetivo de solucionar este problema, Scott Meyers facilitó una solución sencilla (y muy elegante): en lugar de almacenar un puntero a un objeto de tipo Singleton instancial una variable local estática del siguiente modo:

singletonPattern & getInstance(){
static singletonPattern instance;
return instance;

}
El fragmento anterior se conoce como el singleton de Meyers y se basa en, tal y como describe Alexandrecu en su libro Modern C++ Desing:Generic Programming and Patterns Applied, "some compiler magic": un objeto estático de una función es inicializado, en tiempo de ejecución, en el momento de la primera pasada de la definición.

Este par de soluciones son, aparentemente sencillas, y pueden ayudarnos a construir un Singleton mucho más robusto.

En el libro de Alexandrescu mencionado anteriormente plantea otros problemas tales como las referencias muertas (a las cuales aplica soluciones elegantes e ingeniosas) o los problemas derivados de la interacción de los hilos y los singleton.

Desde mi punto de vista el singleton es un patrón de diseño muy sencillo conceptualmente pero que, llegada la hora de implementarlo, no resulta tan evidente como pueda parecer en un principio.

C++ Singleton Pattern (I)

Os dejo un post que había escrito hace mucho tiempo en otro blog; está dedicado a C++ y a los patrones de diseño.

Os propongo una implementación del patrón de diseño Singleton (uno de los patrones de diseño más simples aunque creo que muchas veces lo utilizamos de forma no demasiado apropiada).

El patrón anterior nos garantiza que, desde el momento en que instanciamos un objeto de dicha clase, será esa la única instancia que exista de dicho objeto. Existen multitud de libros acerca de patrones de diseño y con multitud de aplicaciones de los mismos. Yo desde aquí nada más pretendo dejaros mi experiencia y el uso que yo le he dado en mis aplicaciones. Por ejemplo, este patrón lo he utilizado en el desarrollo de un compilador para representar los builtin type. Vamos allá:

En primer lugar definimos la clase singletonPattern y el método que nos permitira obtener una referencia al mismo (hacemos que el constructor sea privado para que no se puedan crear objetos de ese tipo):

class singletonPattern{
private:
/// unique instance of the object
static singletonPattern * instance;
/// Default Constructor
singletonPattern(){}

public:
/*!
Returns the reference
to the unique instance of the object

(if it's the first time create de reference)
*/
static singletonPattern * getInstance(){
if(instance == NULL)
instance = new singletonPattern();
return instance;
}
};

// init the static member
singletonPattern * singletonPattern :: instance = NULL;

El código anterior no estaría completo dado que nos queremos asegurar de que nuestra instancia sea única por lo que tendremos que implementar el constructor de copia y el operador de asignación (no tiene sentido el operador de asignación en el singleton) como privados dentro de nuestra clase singletonPattern. Algo como lo que sigue:

/// Copy Constructor
singletonPattern(const singletonPattern & sp){}

/// Assignement Operator
singletonPattern & operator=(singletonPattern & sp){
return *this;
}

Si quisieramos utilizar esta clase en uno de nuestros programas no tendríamos más que declarar un objeto tal y como a continuación se muestra:
singletonPattern * singleton = singletonPattern::getInstance();

Y listo. Con esto tendremos nuestro patrón de diseño Singleton listo para disponer de el cuando deseemos.

Desde el siguiente enlace podeis descargaros el código fuente completo junto con un makefile:singletonPatterC++.

Hasta pronto!

martes, mayo 01, 2007

Primero de mayo, es increible lo rápido que se me pasa el tiempo últimamente; no sé si será que me estoy haciendo viejo a marchar forzadas o que últimamente tengo bastantes cosas entre manos. Esperemos que sea lo segundo jejejeje.

Este finde no he hecho gran cosa, el sábado a la tarde estuve trabajando un rato en mi proyecto y por la tarde salí de compras (aunque no me compré nada ya tengo ojeadas unas zapatillas y alguna que otra cosilla) y el domingo me fui a Salamanca a pasar el día.

No tengo muchas cosas que contaros así que voy a aprovechar para comenzar una nueva sección en el blog: el mundo de la programación. Simplemente se trata de algunos ejemplos sencillos basados en mis escasos conocimientos y mi corta experiencia de algunos temas que me gustan o de los que me gustaría aprender. Espero que os guste y/o os pueda servir de ayuda. Vamos allá . . . . . .

Vamos a comenzar con un post dedicado a los patrones de diseño y el lenguaje de programación C++. Os propongo una implementación del patrón de diseño Singleton (uno de los patrones de diseño más simples aunque creo que muchas veces lo utilizamos de forma no demasiado apropiada).

El patrón anterior nos garantiza que, desde el momento en que instanciamos un objeto de dicha clase, será esa la única instancia que exista de dicho objeto. Existen multitud de libros acerca de patrones de diseño y con multitud de aplicaciones de los mismos. Yo desde aquí nada más pretendo dejaros mi experiencia y el uso que yo le he dado en mis aplicaciones. Por ejemplo, este patrón lo he utilizado en el desarrollo de un compilador para representar los builtin type. Manos a la obra:

En primer lugar definimos la clase singletonPattern y el método que nos permitira obtener una referencia al mismo (hacemos que el constructor sea privado para que no se puedan crear objetos de ese tipo):

class singletonPattern{
private:
/// unique instance of the object
static singletonPattern * instance;
/// Default Constructor
singletonPattern(){}

public:
/*!
Returns the reference
to the unique instance of the object

(if it's the first time create de reference)
*/
static singletonPattern * getInstance(){
if(instance == NULL)
instance = new singletonPattern();
return instance;
}
};

// init the static member
singletonPattern * singletonPattern :: instance = NULL;

El código anterior no estaría completo dado que nos queremos asegurar de que nuestra instancia sea única por lo que tendremos que implementar el constructor de copia y el operador de asignación (no tiene sentido el operador de asignación en el singleton) como privados dentro de nuestra clase singletonPattern. Algo como lo que sigue:

/// Copy Constructor
singletonPattern(const singletonPattern & sp){}

/// Assignement Operator
singletonPattern & operator=(singletonPattern & sp){
return *this;
}

Si quisieramos utilizar esta clase en uno de nuestros programas no tendríamos más que declarar un objeto tal y como a continuación se muestra:
singletonPattern * singleton = singletonPattern::getInstance();

Y listo. Con esto tendremos nuestro patrón de diseño Singleton listo para disponer de el cuando deseemos.

Desde el siguiente enlace podeis descargaros el código fuente completo junto con un makefile: singletonPatternC++.

El código disponible en el enlace anterior es una primera aproximación. Intentemos añadirle algunas mejoras:

Un primer cambio a realizar sería el de retornar una referencia en lugar de un puntero en el método getInstance(); de este modo evitaríamos que el usuario que obtiene una referencia del objeto intentase aplicarle el operador delete. El prototipo del nuevo método podría ser algo parecido a lo siguiente:

static singletonPattern & getInstance();


Pensemos ahora en que ocurre cuando se destruye el singleton.Realmente no se trata un memory leak tradicional sino un resource leak. El singleton podría haber adquirido diversos recursos del operativo como un socket,un semáforo,...... Con el objetivo de solucionar este problema, Scott Meyers facilitó una solución sencilla (y muy elegante): en lugar de almacenar un puntero a un objeto de tipo Singleton su solución instancia una variable local estática del siguiente modo:

singletonPattern & getInstance(){
static singletonPattern instance;
return instance;

}
El fragmento anterior se conoce como el singleton de Meyers y se basa en, tal y como describe Alexandrecu en su libro Modern C++ Desing:Generic Programming and Patterns Applied, "some compiler magic": un objeto estático de una función es inicializado, en tiempo de ejecución, en el momento de la primera pasada de la definición.

Este par de soluciones son, aparentemente sencillas, y pueden ayudarnos a construir un Singleton mucho más robusto.

En el libro de Alexandrescu mencionado anteriormente plantea otros problemas tales como las referencias muertas (a las cuales aplica soluciones elegantes e ingeniosas) o los problemas derivados de la interacción de los hilos y los singleton. En futuros post puede que ahondemos un poco en estas cuestiones.

Hasta pronto!
Un abrazo!