Foros - Stratos

Programadores => General Programadores => Mensaje iniciado por: wendal en 21 de Julio de 2006, 11:52:46 AM

Título: Singleton vs static
Publicado por: wendal en 21 de Julio de 2006, 11:52:46 AM
Hola

Me gustaría saber lo que opináis acerca de la elección entre una clase singleton que contenga métodos, probablemente inline, vs una clase con métodos estáticos y quizás constantes estáticas. Me gustaría saber lo que opináis sobre ventajas e inconvenientes de ambas opciones, desde el punto de vista del rendimiento.

Mi postura hasta el momento es la de emplear métodos estáticos y constantes estáticas para clases digamos contenedor. Por ejemplo, una clase cMath que contenga constantes estáticas como PI, DEGREES_TO_RAD,... y métodos estáticos como por ejemplo una implementación optimizada del coseno, mientras que usaría un singleton por ejemplo para implementar el patrón State para el estado del juego, una jerarquía con cGameState como superclase con un método virtual doAction() implementado por las subclases singleton cPausedGame y cRunningGame.

La situación que presento creo que es un caso obvio en el que aplicar el singleton al diseño del juego trae ventajas, pero me gustaría saber el coste real que tiene en rendimiento.

Gracias de antemano.
Título: Singleton vs static
Publicado por: tamat en 21 de Julio de 2006, 12:05:50 PM
creo que tu mismo lo has respondido ya. Yo intento hacer static aquellas cosas que no dependen de otras y singleton las que son más dependientes, así puedo controlar cuando se crean y en qué orden.
Título: Singleton vs static
Publicado por: Diferencial en 21 de Julio de 2006, 12:43:59 PM
Explicarme porfavor que es eso de singleton,
Una clase estatica me imagino que te refieres a metodos estaticos, en los que puedes usarlos directamente. Un profesor que tenia yo de java me comento que si abusabas de estos metodos, el mayor incoveniente es que cuando cargas la clase se cargan en memoria todos los metodos y variables estaticas que tenga incluso aquellos que no uses.
Título: Singleton vs static
Publicado por: senior wapo en 21 de Julio de 2006, 01:10:23 PM
Un singleton es una clase diseñada de tal forma que solo permite crear un objeto de esa clase. Si intentas crear un segundo objeto, no te deja o da un error.

El ejemplo más tipico es una clase CApplication.

Lo que te decía tu profesor puede que fuese cosa del Java, no lo se, pero en términos generales, depende del compilador+linker que uses más que nada. Quitar de la imagen ejecutable lo que no se utiliza es una optimización. Suelen llamarla "Dead Code Elimination", por si quieres buscar mas información.
Título: Singleton vs static
Publicado por: CoLSoN2 en 21 de Julio de 2006, 01:43:18 PM
Cita de: "senior wapo"Un singleton es una clase diseñada de tal forma que solo permite crear un objeto de esa clase. Si intentas crear un segundo objeto, no te deja o da un error.
Esa es la restricción que supone el patrón Singleton, pero te olvidas de la utilidad básica del mismo, que es hacer esa única instancia globalmente accesible, desde cualquier punto del código. Como una variable global pero mucho más elegante.

Por cierto, el spelling check este del foro lo podríamos ir quitando, que me subraya todas las palabras...
Título: Singleton vs static
Publicado por: Diferencial en 21 de Julio de 2006, 01:52:42 PM
Como cuando se usa una camara en c++:

Camara::Move(speed);

Os referi a esto o es a la forma de declarar la clase??
Título: Singleton vs static
Publicado por: Lex en 21 de Julio de 2006, 02:07:24 PM
...
Título: Singleton vs static
Publicado por: Flint en 21 de Julio de 2006, 02:14:15 PM
Sin dejar de tener presente que un singleton es una manera de garantizar que una clase tiene únicamente una instancia y que tiene un punto de acceso global (ambas cosas).

Si lo único que necesitas es el punto de acceso global, pues, haz una global de las de toda la vida. Lo suyo es no caer en la singletonitis (convertir todo lo que tocas en un singleton), especialmente con clases que realmente sólo son utilizadas en una pequeña parte del código.

También hay quien dice que recurrir al singleton como manera de determinar el orden de inicialización de instancias estáticas en C++ es un abuso de este patrón y que el hecho de tener globales que dependan de otras globales en un programa es un serio fallo en el diseño del mismo. Para otras personas, ésta es precisamente la única utilidad de los singletons.
Título: Singleton vs static
Publicado por: zupervaca en 21 de Julio de 2006, 02:28:25 PM
Por si te vale de algo en c++ uso singleton:

/// <summary>Template que nos permite acceder a una clase unica</summary>
template <class TYPE> class Singleton
{
// Metodos
public:
/// <summary>Operador -></summary>
TYPE *operator -> ()
{
return this->Instance();
}

/// <summary>Operador *</summary>
TYPE *operator * ()
{
return this->Instance();
}

// Valores privados
private:
/// <summary>Obtener la instancia unica</summary>
TYPE *Instance()
{
static TYPE intance;
return &intance;
}
};

Aun no he probado si asi vale o al final tendre que poner un if y un new como a puesto lex

Y para j2me uso miembros estaticos y en el metodo finalize de la clase que los contiene los igualo a null, asi siempre que llame a paco el basurero los miembros estaticos dejan de existir (en teoria claro)
Título: Singleton vs static
Publicado por: Flint en 21 de Julio de 2006, 02:42:16 PM
Una implementación clásica:

template <typename T>
class Singleton {
  public:
     static T* instance() {
        static T ms_instance;
        return &ms_instance;
     }

  protected:
     Singleton() {}
     virtual ~Singleton() {}

  private:
     Singleton(const Singleton<T>&) {}
     Singleton<T>& operator=(const Singleton<T>&) {}
};



Otra en la que tienes que crear y destruir el singleton explícitamente:

template <typename T>
class Singleton {
  public:
     static T* instance() {
        assert(ms_instance);
        return ms_instance;
     }

     Singleton() {
        assert(!ms_instance);
        ms_instance = static_cast<T*>(this);
     }
     
     virtual ~Singleton() {
        ms_instance = 0;
     }

  private:
     static T* ms_instance;

     Singleton(const Singleton<T>&) {}
     Singleton<T>& operator=(const Singleton<T>&) {}
};

template <typename T> T* Singleton<T>::ms_instance = 0;
Título: Singleton vs static
Publicado por: senior wapo en 21 de Julio de 2006, 03:37:09 PM
Me da cosa ponerlo porque ya sabemos donde acaban los debates semánticos, pero...

Técnicamente hablando, considero que ser accesible globalmente, por más que sea el uso que en la práctica le damos, sea requerimiento para ser singleton.

Single = único :p

Pero vamos, que si, que nos entendemos, que como todo hijo de vecino, cuando pensamos en un singleton es para aplicarlo en objetos globales. Viene bien decirlo.
Título: Singleton vs static
Publicado por: Pogacha en 21 de Julio de 2006, 03:52:28 PM
Cita de: "Lex"Un singleton se declara así:

class Singleton {
  public:
     static Singleton* Instance();
  protected:
     Singleton();
  private:
     static Singleton* _instance;
};

Singleton* Singleton::_instance = 0;

Singleton* Singleton::Instance () {
  if (_instance == 0) {
     _instance = new Singleton;
  }
  return _instance;
}


Para poder usarlo solo tienes que llamar a la función que de devuelve la instancia creada del objeto.
Te falto el delete ... no?
Título: Singleton vs static
Publicado por: Flint en 21 de Julio de 2006, 04:33:16 PM
Cita de: "senior wapo"Me da cosa ponerlo porque ya sabemos donde acaban los debates semánticos, pero...

Técnicamente hablando, considero que ser accesible globalmente, por más que sea el uso que en la práctica le damos, sea requerimiento para ser singleton.

Single = único :p

Pero vamos, que si, que nos entendemos, que como todo hijo de vecino, cuando pensamos en un singleton es para aplicarlo en objetos globales. Viene bien decirlo.

Personalmente, yo recurro a la definición del Design Patterns (Gamma et al 1995, p. 127): The Singleton pattern "ensures a class only has one instance, and provides a global point of access to it."

Pero evidentemente, luego cada cual es libre de hacer lo que quiera.
Título: Singleton vs static
Publicado por: zupervaca en 21 de Julio de 2006, 04:53:39 PM
A mi me gusta la implementacion que he puesto por que es muy sencilla y trabajas muy facilmente.

class pruebas
{
public:
  void mola()
  {
  };
};

...

Singleton<pruebas> p;
p->mola();

Si la funcion "Instance" fuera publica se podria acceder a ella mediante:

Singleton<pruebas> p;
p.Instance();

Asi se podria hacer aquello de crearlo en el orden que se quiera, pero repito que aun no he comprobado si va bien que sea estatico dentro de una funcion, por aquello de aquel otro hilo, me imagino que puede fallar si el compilador hace que la funcion sea inline por ejemplo, aunque aun no estoy seguro.

Como ultimo decir que tener mas de un objeto global a mi se me hace raro, aunque a veces no quede mas solucion, en j2me uso mucho miembros estaticos para ganar velocidad y no repetir datos en memoria, todo es cuestion de tener que adaptarse :?
Título: Singleton vs static
Publicado por: Flint en 21 de Julio de 2006, 05:07:32 PM
Cita de: "zupervaca"Asi se podria hacer aquello de crearlo en el orden que se quiera, pero repito que aun no he comprobado si va bien que sea estatico dentro de una funcion, por aquello de aquel otro hilo, me imagino que puede fallar si el compilador hace que la funcion sea inline por ejemplo, aunque aun no estoy seguro.

Si te refieres a mantener la instancia estática dentro de una función (en este caso el constructor), como también he puesto en mi post anterior, no hay ningún problema. De hecho, es la solución conocida como el Singleton de Meyers; la construcción parte del hecho de que los objetos estáticos dentro de una función sólo son inicializados la primera vez que se llama dicha función.
Título: Singleton vs static
Publicado por: Flint en 21 de Julio de 2006, 05:44:59 PM
Cita de: "Pogacha"
Cita de: "Lex"Un singleton se declara así:

class Singleton {
  public:
     static Singleton* Instance();
  protected:
     Singleton();
  private:
     static Singleton* _instance;
};

Singleton* Singleton::_instance = 0;

Singleton* Singleton::Instance () {
  if (_instance == 0) {
     _instance = new Singleton;
  }
  return _instance;
}


Para poder usarlo solo tienes que llamar a la función que de devuelve la instancia creada del objeto.
Te falto el delete ... no?

Creo que ésa es precisamente la implementación del Singleton de Gamma. ¿Hay un memory leak? Pues depende de cómo lo mires: un memory leak suele ser definido como una acumulación de datos sobre los que se pierde la referencia durante la ejecución del programa, lo que imposibilita su liberación. En este caso, _instance vive en la memoria hasta que la aplicación termina, por lo que no tiene que considerarse un memory leak. De todos modos, no todos los sistemas operativos liberan la memoria que cuelga de un proceso terminado, por lo que, en esos sistemas, si el singleton hubiera accedido a recursos del sistema, se podría producir un resource leak una vez hubiera finalizado el problema. ¿Solución? Recordarse de hacer un delete sobre el singleton manualmente o cambiar de implementación.
Título: Singleton vs static
Publicado por: Pablo Zurita en 21 de Julio de 2006, 05:58:08 PM
Cada vez que reservas memoria, tenes que liberarla en algún momento antes de salir. No es buena práctica dejar sin liberar porque si por alguna razón decidís modificar cuando tiene que morir tu singleton entonces terminas con un memory leak que es importante. Los programas como DevPartner no definen el "leak on exit" solo para molestarte.

BTW, ninguna de esas implementaciones de singleton son thread-safe.
Título: Singleton vs static
Publicado por: zupervaca en 21 de Julio de 2006, 06:01:31 PM
Es cierto la implementacion que he puesto no es segura en hilos.
Título: Singleton vs static
Publicado por: Flint en 21 de Julio de 2006, 06:09:11 PM
Cita de: "Pablo Zurita"BTW, ninguna de esas implementaciones de singleton son thread-safe.

Efectivamente. Una solución sencilla sería sincronizar el método Instance().
Título: Singleton vs static
Publicado por: Vicente en 21 de Julio de 2006, 07:11:01 PM
Entre singletons anda el juego. Uno en C# que es thread-safe y tiene instanciación perezosa (solo se crea cuando se usa por primera vez):


namespace Test
{
public class Singleton
{
private static readonly Singleton instance = new Singleton();

static Singleton() {}
private Singleton() {}

public static Singleton Instance
{
get { return instance; }
}
}
}


Un saludo!

Vicente
Título: Singleton vs static
Publicado por: Diferencial en 21 de Julio de 2006, 08:33:01 PM
Es interesante, lo unico que no me queda claro es cuando usar la clase Singleton.
Una utilidad que se me acaba de ocurrir es cuando solo quieres tener una instancia de tu programa sin que puedan ejecutarlo dos veces.
Podeis poner los principales motivos de usar singleton o cuando lo usais vosotros?
Título: Singleton vs static
Publicado por: Flint en 21 de Julio de 2006, 08:46:59 PM
Cita de: "Diferencial"Es interesante, lo unico que no me queda claro es cuando usar la clase Singleton.
Una utilidad que se me acaba de ocurrir es cuando solo quieres tener una instancia de tu programa sin que puedan ejecutarlo dos veces.
Podeis poner los principales motivos de usar singleton o cuando lo usais vosotros?

Siguiendo estrictamente la definición, cuando quieras asegurar que una instancia de una determinada clase sea la única existente en el programa, quieras tener acceso global a ella, y tener una única variable corriente no te resulte suficiente o apropiado; desde luego es algo dependiente de la aplicación. Una clase que típicamente se implementa como singleton es la de logging. Otros usos habituales son los diferentes managers de un programa (render, audio, etc...), aunque la utilidad y corrección real en esos casos es más discutible porque el código de render, audio, etc. no suele necesitar un acceso global, sino que se utiliza en una parte del código pequeña y específica. Si la visibilidad del objeto en cuestión no debe ser global, entonces olvídate de singletons, y céntrate en asegurar que sólo pueda crearse una instancia del mismo (lanzando una excepción, por ejemplo, en el caso de que esto no se cumpla).

Se suele considerar el singleton como un anti-patrón de diseño porque evita tener que pensar en la visibilidad de un objeto y realmente no es sino una manera más fina de tener globales en tu programa, con todo lo que ello conlleva.
Título: Singleton vs static
Publicado por: Ruben en 21 de Julio de 2006, 08:56:01 PM
Cita de: "Pablo Zurita"

BTW, ninguna de esas implementaciones de singleton son thread-safe.

El operador new es "thread-safe", asi que teoricamente (y si lo dices por el new), la implementacion del singleton que usa new es "thread-safe". Aunque debes de liberar la memoria reservada a mano.

Y con la otra implementacion, evitas lo de liberar la memoria a mano pero entra en conflicto con las aplicaciones con multiples hilos.

Entonces, ¿porque dices que ninguna es "thread-safe"?
Título: Singleton vs static
Publicado por: Flint en 21 de Julio de 2006, 09:02:03 PM
No son thread-safe. Por ejemplo, en la que ha puesto Lex, puede suceder:

- Un thread evalúa la expresión if (_instance == 0) y encuentra que es verdadera.
- Ahora viene otro thread, entra el if porque la expresión es verdadera y construye la instancia.
- Regresa el thread anterior al punto en el que quedó, y éste también construye una instancia.

Con lo que tenemos dos instancias y ¡pam!, nos hemos cargado el invento.
Título: Singleton vs static
Publicado por: Pogacha en 19 de Febrero de 2007, 12:49:26 PM
Para evitar esto se usa el doble chequeo:
theclass* getInstance() {
 if(!instance) {
   LOCK_THREAD
   if(!instance) instance = new theclass;
   UNLOCK_THREAD
 }
 return instance;
}


<HR>

Yengo este problema:

template<class T> class Singleton {
    Singleton()
    void operator=(const Singleton& );
  public:
    T* getInstance() {
          static T i;
          return &i;
   }
};

class Usandolo : public Singleton<Usandolo> {
 public:
   Usandolo();
   friend class Singleton<Usandolo>;
};


En modo debug me anda perfecto, pero en retail me crea multiples instancias ... VC 6.0 ... alguna solución?

Saludos
Título: Singleton vs static
Publicado por: Pogacha en 19 de Febrero de 2007, 04:48:03 PM
No soy el unico.

http://www.thescripts.com/forum/threadnav507963-1-10.html

No encontré solucion otra que desactivar optimizaciones, vere si puedo instalar el VisualExpress 2005

Si alguien sabe de algo se agradecera enormemente.