Stratos: Punto de Encuentro de Desarrolladores

¡Bienvenido a Stratos!

Acceder

Foros





Singleton vs static

Iniciado por wendal, 21 de Julio de 2006, 11:52:46 AM

« anterior - próximo »

wendal

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.

tamat

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.
Por un stratos menos tenso

Diferencial

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.
PARA TENER COSAS QUE NUNCA HAS TENIDO, TENDRÁS QUE HACER COSAS QUE NUNCA HAS HECHO.

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.

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.

CoLSoN2

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...
Manuel F. Lara
Descargar juegos indie  - blog sobre juegos indie y casual
El Desarrollo Personal.com  - blog sobre productividad, motivación y espíritu emprendedor

Diferencial

Como cuando se usa una camara en c++:

Camara::Move(speed);

Os referi a esto o es a la forma de declarar la clase??
PARA TENER COSAS QUE NUNCA HAS TENIDO, TENDRÁS QUE HACER COSAS QUE NUNCA HAS HECHO.

Lex


Flint

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.

zupervaca

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)

Flint

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;

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.

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?

Flint

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.

zupervaca

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 :?

Flint

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.






Stratos es un servicio gratuito, cuyos costes se cubren en parte con la publicidad.
Por favor, desactiva el bloqueador de anuncios en esta web para ayudar a que siga adelante.
Muchísimas gracias.