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á . . . . . .
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:
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:
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;
}
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!
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!
3 comentarios:
Sólo te voy poner una palabra:
FRIKI!!!!!
(el "de mierda" me lo reservo pq me caes bien :P)
Besos
Va mono! Entro pa ver que me cuentes de tu vida y, aunque encuentro unos cuantos post en los que te enrolles con algo interesante, vas ahora y empieces a poneme código aquí...!jajaja. Tas como un toro.
Yo nada, 5 días de congreso, sin facer nada y ahora toca ponese a tope, recuperar lo que no hice y empezar con lo que vien.
Así me gusta, que empieces otra vez con el blog, que estaba hasta los huevos de vete el tatuaje,jajajaja!
Cuidate monín. Nos vemos por la red hasta que vuelvas por equí ;)
Un abrazu
No te enfades Andre jajjajaja.
Mono,ya veo que sigues tan ocupao como siempre, clases, prácticas, fotos, congresos,... ¿quién da más?
Espero que todo vaya bien chicos!
Un abrazo
Publicar un comentario