Foros - Stratos

Programadores => General Programadores => Mensaje iniciado por: DraKKaR en 03 de Octubre de 2004, 12:27:43 PM

Título: No Me Gustan Los Singletones
Publicado por: DraKKaR en 03 de Octubre de 2004, 12:27:43 PM
 Primero veamos si lo he entendido todo bien. Un singleton es una clase de la que únicamente puede instanciarse un único objeto. La forma de hacerlo sería por ejemplo, que para instanciar de una clase haya que hacerlo a través de una función tal que así:


MiClase Instanciamela(void){
   static MiClase *obj=NULL;
   if (!obj)
       obj=new MiClase;
   return obj;
}


Bien, yo no digo que no sea interesante que, si de una clase sólo puede haber una instancia, recurrir a este truco para asegurarse de ello. Lo que realmente no me gusta es que, el programador que use este sistema, puede estar intentando instanciar más de una vez un objeto de este tipo (mediante esta función) sin saber que está obrando mal.

Pondré un ejemplo con Direct3D: soy un progamador que no tiene mucha idea y en mi programa intento llamar 3 veces a la función Direct3DCreate9. Si uso un singletón como el anterior, podré hacerlo sin problemas, simplemente la función creará sólo la primera vez el objeto y las otras veces me devolverá nua instancia a ese primer objeto. ¡Pero el programador no sabrá que lo que está haciendo está mal! Incluso como funciona el programador puede llegar a pensar que en realidad está instanciando 3 veces el objeto, pero en realidad solo lo ha hecho una vez.

Los singletones me parecen una forma de "engañar" al programador. Asumimos que el programador es estúpido y que intentará hacer cosas que no se deben hacer. Entonces, parece que la cuestión de los singletones sea:
"Dejemos que el programador escriba un mal programa, pero que en realidad funcione"!

Yo creo que una función que instancie un objeto, debería siempre instanciar un objeto de este tipo. Sin recurrir a trikiñuelas dentro de ella. Para intentar subsanar el error del programador "cliente".
Si un objeto sólo puede instanciarse una vez deberíaestar todo bien explicado en la documentación de la clase.

Veo mucho más útil reescribir la clase anterior de esta forma:

MiClase Instanciamela(void){
   static MiClase *obj=NULL;
   if (obj)
       throw ErrorDeLaMuerte;
   obj=new MiClase;
   return obj;
}


De esta forma el programador sabe que ha intentado hacer algo que está mal, al menos lógicamente y lo corregirá de la forma adecuada. Si se usa un singletón de la forma anterior, el pgroamador no sabe que lo que está intentando hacer (la idea que tiene en mente) está mal planteada o tiene algún problema de comprensión con la clase en cuestión.


Bueno, eso es lo que pienso. ¿Qué opinais? Si me ilumináis, pues mejor que mejor.
Título: No Me Gustan Los Singletones
Publicado por: sés en 03 de Octubre de 2004, 12:57:07 PM
 Pues te pongo una respuesta rápida:

Imagina la típica clase única (singleton) CVideo, encargada dibujar.

Suponemos que el programador solo instancia una vez CVideo para poder dibujar y hace algo como:
CVideo vid = new CVideo();
o
CVideo vid = CVideo::Instanciamela();

:) Bien, ese programador tiene su objeto único CVideo.

Pero... ¿qué pasa con las tropecientas funciones que pueden querer dibujar? ¿Cómo encuentran CVideo vid? ¿La pones en un .h para que el resto de clases la conozcan?

Según tu modelo las clases de la librería (que puede que ni sean tuyas) deben conocer tu variable, no solo la clase.
¿Qué pasaría si una clase externa llama antes a CVideo::Instanciamela()? Pues que ese programador "listo"sabrá que no puede instanciar otra vez CVideo... y además se quedará sin poder hacer nada :P

Espero que esto te aclare algo, no sé si lo expliqué bien :huh:
Título: No Me Gustan Los Singletones
Publicado por: DraKKaR en 03 de Octubre de 2004, 01:02:58 PM
 ses:
Eso se arreglaría con dos funciones estáticas (de clase):


CVideo *CVideo::Instanciamela();
CVideo *CVideo::Damela();


Una instanciaría un nuevo objeto de la clase, y otra función simplemente lo devolvería.

La cuestión es que la función Instanciamela no "engañe" al programador haciendo creer que va a instanciar un objeto de esa clase, cuando sólo lo instanciará la primera vez que la llames. Las otras simplemente lo devolverá.
Título: No Me Gustan Los Singletones
Publicado por: ethernet en 03 de Octubre de 2004, 01:11:24 PM
 Umh, cuando usas un singleton es porque quieres solo una instancia de un objeto. Creo que deberías leer un poco más acerca del pattern Singleton y enterarte bien de para qué sirve. sés te ha dado una pista.
Además eso que has puesto NO es un singleton, un singleton sería esto:


class MyClass
{
private:

MYClass(){}
public:

static MyClass& Get(){ static MyClass h; return h;}
};


Así es imposible crear una instancia de MyClass.
Creo que tú lo que buscas es una variable global XD

Título: No Me Gustan Los Singletones
Publicado por: sés en 03 de Octubre de 2004, 01:45:28 PM
 
Cita de: "DraKKaR"Eso se arreglaría con dos funciones estáticas (de clase):


CVideo *CVideo::Instanciamela();
CVideo *CVideo::Damela();


¿Según eso tendrías que hacer algo así?
CVideo vid = CVideo::Instanciamela();
if( !vid ) vid = CVideo::Damela();

Uhm... no le veo la ventaja.

Creo que, como dice ethernet, lo más parecido a lo que buscas es una variable global.

Ahora se me ocurre otra cosa. Quizás te sirva algo del tipo:
Class CVideo {
  static CVideo *instance = NULL;
  static const int secretCode = 53452345;

  CVideo( int code=0 )
  {
     if( code != secretCode ) {
        // lanzar EXCEPCIONQUETECAGAS
     }
  }

public:
  CVideo getInstance() {
     if( !instance ) instance = new CVideo( secretCode );
     return instance;
  }  
}



Así, si alguien intenta nacer un new CVideo(), le da un pete del copón.
El que llame a CVideo::getInstance() evidentemente tiene que saber que es un singleton. Si no lo sabe, mal vamos.
Título: No Me Gustan Los Singletones
Publicado por: BeRSeRKeR en 03 de Octubre de 2004, 01:49:03 PM
 Utilizando la forma de singleton que ha puesto ethernet, el usuario no podrá crear una instancia de la clase ya que el constructor es privado por lo que el compilador le lanzará un error. Sólo podrá acceder a la única instancia creada por el singleton.

Saludos.
Título: No Me Gustan Los Singletones
Publicado por: ethernet en 03 de Octubre de 2004, 01:54:33 PM
 No creo que se trate de secrets code ni nada así. Cuando haces un singleton hay dos cosas importantes:
1.- sabes que es un singleton y el coder que lo usa lo sabe
2.- sabes que va a ser un pattern lazy (tal cual lo hemos definido antes) con lo cual hay que saber qué clases pueden ser singletonizadas y cuales no.

Si quieres ver un singleton puedes ir COTW! (http://www.stratos-ad.com/forums/index.php?act=ST&f=28&t=1771 ) en el que hay una discusión bastante interesante
tb en el cotd de flipcode: http://www.flipcode.com/cgi-bin/msg.cgi?sh...orum=cotd&id=-1
Título: No Me Gustan Los Singletones
Publicado por: sés en 03 de Octubre de 2004, 02:24:06 PM
 No estoy muy fino en estos temas, pero leí por ahí que el modelo que ha puesto ethernet no es bueno. Supongo que en algunos casos sirve, pero en otro no.
La principal razón que daban era que el objeto se construye siempre, aunque nadie lo quiera utilizar.
Título: No Me Gustan Los Singletones
Publicado por: ethernet en 03 de Octubre de 2004, 03:26:37 PM
 Cual de todos los modelos? El que puse antes es lazy, no sé a qué te refieres.
De todas maneras por ahí iban los tiros cuando decía que hay que saber qué clases pueden ser usadas con ese tipo de singletones.

saludos
Título: No Me Gustan Los Singletones
Publicado por: CoLSoN2 en 03 de Octubre de 2004, 06:23:41 PM
 Ante el ejemplo de ethernet de usar una variable static estática dentro del método ::get(), debo decir que tiene uninconveniente:

Yo antes usaba ese método porque me parecía más limpio, pero en modo Release (en Debug no) la aplicación me hacía cosas rarísimas, y después de mucho investigar lo que ocurría es que la variable static (static instancia; return instancia;) se creaba varias vecess (¿?). Igual era porque la aplicación usa threads o vete a saber qué, pero lo cambie a un atributo static (y dinámico, para poder destruirlo cuando quiera) de la clase, y listo.
Título: No Me Gustan Los Singletones
Publicado por: Mars Attacks en 03 de Octubre de 2004, 07:21:50 PM
 @Drakkar: No Me Gustan Los Singletones

Pues apártalos y cómete las patatas.
Título: No Me Gustan Los Singletones
Publicado por: ethernet en 03 de Octubre de 2004, 07:37:31 PM
Cita de: "CoLSoN2"Ante el ejemplo de ethernet de usar una variable static estática dentro del método ::get(), debo decir que tiene uninconveniente:

Yo antes usaba ese método porque me parecía más limpio, pero en modo Release (en Debug no) la aplicación me hacía cosas rarísimas, y después de mucho investigar lo que ocurría es que la variable static (static instancia; return instancia;) se creaba varias vecess (¿?). Igual era porque la aplicación usa threads o vete a saber qué, pero lo cambie a un atributo static (y dinámico, para poder destruirlo cuando quiera) de la clase, y listo.
precisamente por eso odio los singletones, por los problemas de ese tipo, singletones SUCKSSS  
Título: No Me Gustan Los Singletones
Publicado por: CoLSoN2 en 04 de Octubre de 2004, 12:03:10 AM
Cita de: "ethernet"
precisamente por eso odio los singletones, por los problemas de ese tipo, singletones SUCKSSS
pero como he dicho, eso tiene solución.
Título: No Me Gustan Los Singletones
Publicado por: ethernet en 04 de Octubre de 2004, 12:26:39 AM
 querido colsy, en esta vida todo tiene solución menos la muerte
Título: No Me Gustan Los Singletones
Publicado por: DraKKaR en 04 de Octubre de 2004, 12:34:47 PM
 Bueno, gracias a todos por las respuestas. Lo meditaré más profundamente a ver donde podría poner un singletón y si "me gusta como keda" XD.

Suopngo ke la calse principal del motor, de la que solo debería haber una isntancia, podría ser un buen ejemplo.
Título: No Me Gustan Los Singletones
Publicado por: sés en 04 de Octubre de 2004, 01:09:06 PM
 Creo que lo mejor es lo que dijo Mars, si no te gusta... pues no lo uses y punto. Es lo que hago con todos los "patrones".

Hace un tiempo me dieron un curso sobre patrones y mi conclusión es:
Alguien se aburría, puso nombres a cosas que todos hacemos constantemente cuando programamos y nos los venden como la repanocha.

Claro, que en informática siempre es así. A la gente le gusta poner nombres chulos a auténticas chorradas para poder vacilar en las reuniones... (nooo)
Título: No Me Gustan Los Singletones
Publicado por: martiño en 22 de Octubre de 2004, 03:08:27 AM
 - Desde un punto de vista conceptual un singleton no es mas que una variable global mejorada (eso no lo digo yo que lo dice en el "Design Patterns") y las variables globales nunca fueron buenas, se debe usar cuando no se pueden hacer las cosas de otra forma.

- Por otra parte decir que la implementacion de ethernet del singleton es la mas habitual. Todo son ventajas, no hay que usar un "if", se llama al destructor del singleton siempre al cerrarse el programa y no es cierto que se instancie siempre el objeto aunque no lo necesites, ya que las variables estaticas dentro de una funcion se inicializan la primera vez que la función se llama, no al empezar el programa. Ademas, y si no me falla la memoria, esa forma la inventó Meyers, que no es poco.
Título: No Me Gustan Los Singletones
Publicado por: Grugnorr en 22 de Octubre de 2004, 07:47:14 AM
 Los Singleton en C++ son _necesarios_ , el órden de creación de variables globales entre distintas compilation units( librerías, exe... ) no es ni predecible ni portable. En cuanto tengas que una depende de la otra....

Los Singleton en C#, Java y demás lenguajes puros es la única forma de tener una "variable global", ya que no existen las variables fuera de clases

Yo resumiría que en cuanto el sistema es minimamente complejo...

PD: Aunque los Patterns fueran sólo "nombres molones a cosas hechas por siempre", ya serían útiles para poder explicarle a otra persona qué leches quieres decir con eso de un Listener, etc

PD2: El libro Design Patterns debe ser el que más me ha enseñado de programación de los muchísimos que he leido. Sés, lo has leido? :blink:  
Título: No Me Gustan Los Singletones
Publicado por: sés en 22 de Octubre de 2004, 08:24:13 AM
 
Cita de: "Grugnorr"Aunque los Patterns fueran sólo "nombres molones a cosas hechas por siempre", ya serían útiles para poder explicarle a otra persona qué leches quieres decir con eso de un Listener, etc
Estoy de acuerdo. Pero creo que no me has entendido del todo. Hay "Desing Patterns" que sí, que vale, que son útiles... incluso algo "nuevo", pero la mayoría son solo nombres que han puesto a cosas que casi todos hacemos sin que nadie nos las explique.

Es como si yo ahora le pongo un nombre al código con el que recorro un array, lo hago con varias cosas más y al conjunto le pongo un nombre "molón" como... digamos... ¿"Design Patterns"? :P

Ojo: Yo NO digo que estén mal, al contrario, pero se venden como si fuera el invento del siglo o algo nuevo y simplemente son cosas viejas que alguien juntó y las puso nombres.


Cita de: "Grugnorr"El libro Design Patterns debe ser el que más me ha enseñado de programación de los muchísimos que he leido. Sés, lo has leido? :blink:
No, no lo he leído, pero me han dado un curso en el que me explicaron bastantes patrones y mi conclusión fue esta. Salí igual que entré, no me enseñaron nada que no supiera ya... aparte de los nombres que, por cierto, he olvidado casi todos.

Personalmente no me interesa cómo ha decidido alguien llamar a algo que llevo escribiendo años.

"Mira, que ilu, ahora puedo llamar a este cacho de código Message Facade..." Muy útil, sí señor :lol:
Título: No Me Gustan Los Singletones
Publicado por: ethernet en 23 de Octubre de 2004, 03:18:10 PM
Cita de: "Grugnorr"Los Singleton en C++ son _necesarios_ , el órden de creación de variables globales entre distintas compilation units( librerías, exe... ) no es ni predecible ni portable. En cuanto tengas que una depende de la otra....

precisamente esa es una gran ventaja en algunos sistemas, con el singleton puedes perfectamente saber en qué orden se contruyen y se destruyen las instancias de las clases singletonizadas, lo cual es muy adecuado para diferentes subsitemas que dependen a su vez de otros

saludos
Título: No Me Gustan Los Singletones
Publicado por: Grugnorr en 23 de Octubre de 2004, 04:22:40 PM
 Eso es precisamente lo que intentaba explicar  :P .
Título: No Me Gustan Los Singletones
Publicado por: martiño en 23 de Octubre de 2004, 07:35:56 PM
 
CitarEstoy de acuerdo. Pero creo que no me has entendido del todo. Hay "Desing Patterns" que sí, que vale, que son útiles... incluso algo "nuevo", pero la mayoría son solo nombres que han puesto a cosas que casi todos hacemos sin que nadie nos las explique.

Que levante la mano el que habia hecho por su cuenta un "singleton" antes de oir hablar de el, o un "state" o un "visitor".
Título: No Me Gustan Los Singletones
Publicado por: sés en 24 de Octubre de 2004, 12:47:50 AM
 
Cita de: "martiño"Que levante la mano el que habia hecho por su cuenta un "singleton" antes de oir hablar de el, o un "state" o un "visitor".
*levanta la mano*

Yo he hecho cosas muy parecidas a eso. Y vamos... los singletons los uso desde antes de saber C++; la típica función que te devuelve un objeto (estructura o variable) que solo es inicializado o creado una vez... como que no es nuevo.
Título: No Me Gustan Los Singletones
Publicado por: tamat en 30 de Noviembre de 2004, 07:10:33 PM
 Pues Ses, será que eres un iluminado, porque yo antes de leer el design patterns me dedicaba a lanzar punteros por todo el código hasta que leí el patron Singleton.

Y como han dicho por ahí arriba es una buena manera de etiquetar diferentes maneras de organizar el código, siempre va bien para comunicarte con otros programadores.
Título: No Me Gustan Los Singletones
Publicado por: sés en 01 de Diciembre de 2004, 09:15:37 AM
 No, no soy ningún iluminado :P

Nunca he dicho que los patrones estén bien o mal. Lo que si digo es que nos los venden como la repanocha de la programación y el diseño.

Cuando en el trabajo me enviaron a un curso en el que nos iban a enseñar patrones, al terminar mi sensación fue de "coño, me han timado" (bueno, más bien a la empresa ^_^).

A ver, algunos patrones están bien, algunos muy bien y otros... en fin, están. Pero todo eso no es más que estructuras y métodos para hacer ciertas cosas que, si nadie te las enseña, acabarás descubriendo tú solito. La única diferencia es que tú no les pondrás esos nombres tan "guays". En fin, que se le va a hacer, estamos en la época de los nombres chulos y las siglas.

Yo llevo bastantes años dando al teclado y ese curso me sirvió más bien de poco. Lo único que saqué fue un montón de nombres para llamar a las cosas que yo ya hacía.


P.D.: Ah, sí... ya olvidé casi todos los nombres.
Título: No Me Gustan Los Singletones
Publicado por: CoLSoN2 en 01 de Diciembre de 2004, 09:50:03 AM
Cita de: "sés"Lo único que saqué fue un montón de nombres para llamar a las cosas que yo ya hacía.
A parte de que para mí sí son útiles para aprender nuevas formas de solucionar ciertos problemas de POO, no crees que ya por el hecho de tener un nombre que "todos los programadores conocen" (o deberían) ya es un logro? Así si hablas con alguien en el curro, sea en el que llevas 5 años o en uno al que acabas de llegar, puedes explicar perfectamente como pretendes diseñar una determinada arquitectura sólo utilizando esos nombres, y todos te entenderán.
Título: No Me Gustan Los Singletones
Publicado por: sés en 01 de Diciembre de 2004, 10:16:35 AM
 Ya lo he dicho varias veces. Ni me gustan ni me disgustan.

De lo único que me quejo es que nos venden nombres de cosas (que cualquiera que lleve cierto tiempo programando conoce la mayor parte de ellas) como algo mágico.


Es como enseñar a un novato un bucle como este:
for( int i=0; i<a.length; i++ ) System.out.println( a[i] );

Y decirle:
- Esto es el patrón "Array recorrer".

¿Está bien que sepa cómo llamarlo para que otros le entiendan? Pues sí. Pero no deja de ser un trozo de código genérico para recorrer un array.

No es nada mágico, y lo venden como si lo fuera.

Como en todo, a algunos les parecerá la releche y a otros una castaña. A mí simplemente me parece que es algo útil, pero no más que un "Code of the Day", y que se le da demasiada importancia... a algunos les hablas de "Design Patterns" y tienen un orgasmo XD
Título: No Me Gustan Los Singletones
Publicado por: Pogacha en 02 de Diciembre de 2004, 12:39:26 AM
 Todavia no entiendo por que  (supongo las complicaciones que tendria el compilador) no existe la maldita instancia unica de clase:

class {
 // por ejemplo manipulador de memoria o para lo que se use un singleton;
private:
this();
 ~this();
} InstanciaUnica;

Donde el linker la instancie y destruya.

Así serviria de namespace con miembros privados y heredables para su uso:

En la herencia no se crearía una instancia sino que solo daria accesos a todos los miembros de la instancia unica pues estos son estaticos y unicos.

class TUsador_1_De_LaInstanciaUnica : public InstanciaUnica
{
  // Por ejemplo render opengl
} ;

class TUsador_2_De_LaInstanciaUnica : public InstanciaUnica
{
  // Por ejemplo render directx
} ;

Igual esto no contribulle a nada, es solo un loco pensamiento, seguramente hay muchas razones por las cual esto no se pudo implementar en el c++.

Saludos
PD: no me hagan caso  (asco) .
Título: No Me Gustan Los Singletones
Publicado por: fiero en 05 de Diciembre de 2004, 10:14:41 PM
 Estaba leyendo por ahí y al toparme con este post http://www.flipcode.com/cgi-bin/fcmsg.cgi?...read_show=24426 me ha hecho gracia y me he acordado de lo que dice sés. Estoy totalmente deacuerdo con sés, la gente se aburre y pone nombres a cosas, eso es bueno, para reconocer ciertos hábitos de programación, pero tampoco hay que tomarselo como la revolución de la programación ni pensar que si no se dominan todos esos nombres no se puede programar bien XD. En el post del link se habla del "Patrón de diseño del pollo y el huevo", vamos, pa cagarse XDD

un saludo
Título: No Me Gustan Los Singletones
Publicado por: Javi SJ Cervera en 06 de Diciembre de 2004, 12:59:51 AM
 Yo he visto como NeoEngine usa singletones, y creo que está bastante bien.

La principal clase del engine es la clase "Core". No necesitas instanciar nada, sólo hacer Core::Get()->metodo(). La primera vez que llamas a Core::Get(), se creará una instancia "Core" y se devolvera el handle, el resto de las veces sólo devuelve el handle al objeto, para asegurarse de que sólo exista uno en la aplicación.
Título: No Me Gustan Los Singletones
Publicado por: CoLSoN2 en 06 de Diciembre de 2004, 01:31:24 AM
 Bueno, creo que todos sabemos cómo funciona el patrón en cuestión xD
Título: No Me Gustan Los Singletones
Publicado por: Pogacha en 06 de Diciembre de 2004, 01:07:24 PM
 En definitiva sigo pensando que los singletones son algo así como querer patronizar algo unico, o sea, decir la forma del planeta tierra es geoide (geoide=con forma del planeta tierra), lo cual me parece absurdo, ahora si entramos en que un singleton es un caso particular de una clase con numero de instancias controladas donde el numero maximo limitador es 1, me parece igual de ridiculo

Si es algo unico, debe ser estatico y punto (por ahora no me convence ningún argumento), lo logico sería hacer datos estaticos y clases para manipularlos y un estatico manipulador de accesos.

Saludos.
Título: No Me Gustan Los Singletones
Publicado por: ethernet en 06 de Diciembre de 2004, 01:27:05 PM
 Lo que me gustaría ver de una vez es una implementación de singleton que fuera independiente de compilador, SO y demás cosas, que no hubiera problemas si pillo la referencia desde funciones con distinto heap al del proceso ppal, etc. Eso sí que sería un auténtico singleton

Por lo demás me da la impresión de que os estáis metiendo en filosofías que no llevan a nada.

saludos

PD: todo lo que he dicho aplicado a c++ of course