Foros del Web » Programando para Internet » PHP » Frameworks y PHP orientado a objetos »

Singleton: implementacion

Estas en el tema de Singleton: implementacion en el foro de Frameworks y PHP orientado a objetos en Foros del Web. He visto innumerables implementaciones de Singleton...todas diferentes... Código PHP: Class  Singleton  {    /*      Primero se crea la instancia y se imprime 'Hey',   e inmediatamente luego se ejecuta el constructor,   imprimiendose ' boy!'   */    public function  __construct (){     echo  ' boy!' ; ...
  #1 (permalink)  
Antiguo 19/07/2011, 09:40
Avatar de Italico76  
Fecha de Ingreso: abril-2007
Mensajes: 3.303
Antigüedad: 13 años, 3 meses
Puntos: 292
Singleton: implementacion

He visto innumerables implementaciones de Singleton...todas diferentes...

Código PHP:
Class Singleton {

  
/* 
    Primero se crea la instancia y se imprime 'Hey',
  e inmediatamente luego se ejecuta el constructor,
  imprimiendose ' boy!'
  */
  
public function __construct(){
    echo 
' boy!';
  }

  static function 
arranque(){
    static 
$instancia 0;  
  
   
// podria haber chequeado: !is_object($instancia)
    
if (!($instancia instanceof singleton)){
      echo 
'Hey';
      
$instancia = new singleton;
    }    
  }  

#

/* Imprime SOLO UNA VEZ: Hey boy */
$x singleton :: arranque();
$x singleton :: arranque();
$x singleton :: arranque(); 
La de arriba es mia...pero aca otra... por ejemplo:

Código PHP:
<?
class Database 

    
// Store the single instance of Database 
    
private static $m_pInstance

    private function 
__construct() { 
      echo 
'Test ..';
    } 

    public static function 
getInstance() 
    { 
        if (!
self::$m_pInstance
        { 
            
self::$m_pInstance = new Database(); 
        } 

        return 
self::$m_pInstance
    } 
}
Mi duda: la puedo hace de CUALQUIER forma ? (mas alla de evitar clonacion del objeto, etc) o hay ventajas ? GRACIAS!
__________________
Salu2!
  #2 (permalink)  
Antiguo 19/07/2011, 09:52
Avatar de jahepi
Colaborador
 
Fecha de Ingreso: diciembre-2004
Ubicación: Querétaro
Mensajes: 1.124
Antigüedad: 15 años, 7 meses
Puntos: 43
Respuesta: Singleton: implementacion

Hola Italico76 !

Con que entiendas conceptuálmente cual es el propósito del patrón la implementación puede variar de muchas formas.

Cito de la wikipedia, que fue lo primero que encontré :
Cita:
Su intención consiste en garantizar que una clase sólo tenga una instancia y proporcionar un punto de acceso global a ella.
En cuanto a la implementación de la primera opción veo un detalle y es que tienes el constructor público, alguien que utilice la clase, accidentalmente podría crear "n" instancias sin saberlo.

Un saludo y suerte !
__________________
Una contraseña es como la ropa interior. No deberías dejarlas afuera a la vista de otras personas, deberías cambiarla regularmente, y ni se te ocurra prestarla a extraños.
  #3 (permalink)  
Antiguo 19/07/2011, 09:56
Avatar de masterpuppet
Software Craftsman
 
Fecha de Ingreso: enero-2008
Ubicación: Montevideo, Uruguay
Mensajes: 3.550
Antigüedad: 12 años, 5 meses
Puntos: 845
Respuesta: Singleton: implementacion

Hay algunos puntos a tener en cuenta a la hora de hacer un singleton en PHP,

Obligatorio
  1. El constructor debe ser privado
  2. La clase debe sobrescribir __clone

Opcional
  1. Por lo general el metodo que para obtener el objeto se denomina getInstance

Código PHP:
Ver original
  1. class Singleton
  2. {
  3.  
  4.     private static $_instance;
  5.  
  6.     private function __construct()
  7.     {}
  8.  
  9.     public static function getInstance()
  10.     {
  11.         if (!self::$_instance) {
  12.             self::$_instance = new self;
  13.         }
  14.         return self::$_instance;
  15.     }
  16.  
  17.     private function __clone()
  18.     {}
  19. }

Ten en cuenta que es considerado por muchos(me incluyo) un anti-pattern y utilizarlo para la conexión a la bbdd es una pesima idea(esto te lo comento porque la clase de ejemplo es Database).

Saludos.
__________________
http://es.phptherightway.com/
thats us riders :)
  #4 (permalink)  
Antiguo 19/07/2011, 10:15
Avatar de GatorV
$this->role('moderador');
 
Fecha de Ingreso: mayo-2006
Ubicación: /home/ams/
Mensajes: 38.567
Antigüedad: 14 años, 1 mes
Puntos: 2135
Respuesta: Singleton: implementacion

Respecto al código que expones, la primera versión no es totalmente POO, ya que el operador static sobre una variable solo hace que esa variable sea estatica y se usaba cuando haces funciones, no en POO.

En POO se usa una versión como indica @masterpuppet.

Saludos.
  #5 (permalink)  
Antiguo 19/07/2011, 10:53
Avatar de Italico76  
Fecha de Ingreso: abril-2007
Mensajes: 3.303
Antigüedad: 13 años, 3 meses
Puntos: 292
Respuesta: Singleton: implementacion

jahepi: ahora caigo en cuentas del private del __contruct() que ademas previene que la clase pueda ser heredada (creo) .. gracias

Cita:
Respecto al código que expones, la primera versión no es totalmente POO, ya que el operador static sobre una variable solo hace que esa variable sea estatica y se usaba cuando haces funciones, no en POO.
Pues..gracias! la verdad pensandolo un poco....tienes razon! no es una propiedad sino una variable "local" no-local

Una cosa..... y es que me confunde horrible la sintaxis que usa masterpuppet... con eso de new self por ejemplo... que son cosas que no se ven tan seguido (o yo no las veo)

Es que hay una sintaxis casi especifica para Singleton ? o... se puede hacer bien.... usando funciones como is_object() o get_instance() ?

Devolver el objeto es para poder usar metodos encadenados o... hay alguna otra razon ?

Nuevamente gracias!
__________________
Salu2!
  #6 (permalink)  
Antiguo 19/07/2011, 10:58
Avatar de GatorV
$this->role('moderador');
 
Fecha de Ingreso: mayo-2006
Ubicación: /home/ams/
Mensajes: 38.567
Antigüedad: 14 años, 1 mes
Puntos: 2135
Respuesta: Singleton: implementacion

self, siempre se refiere a la misma clase, es lo mismo que usar new Clase(), pero dentro de la clase y como estas implementando singleton, vas a devolver la misma instancia, por eso es igual usar new self();

is_object no se puede usar, ya que solo comprueba si la variable es un objeto, y tienes que comprobar si mas bien la variable es una instancia de la clase.

get_instance desconozco que hace esa función.

No hay una sintaxis obligatoria, simplemente es que en tu primera llamada a getInstance() si la instancia de la clase no existe la cree y la devuelva.

Podrías usar algo así también:
Código PHP:
Ver original
  1. public static function getInstance()
  2. {
  3.        if (!(self::$_instance instanceof self)) {
  4.              self::$_instance = new self();
  5.        }
  6.  
  7.        return self::$_instance;
  8. }

Saludos.
  #7 (permalink)  
Antiguo 19/07/2011, 11:08
Avatar de Italico76  
Fecha de Ingreso: abril-2007
Mensajes: 3.303
Antigüedad: 13 años, 3 meses
Puntos: 292
Respuesta: Singleton: implementacion

Cita:
Iniciado por GatorV Ver Mensaje
is_object no se puede usar, ya que solo comprueba si la variable es un objeto, y tienes que comprobar si mas bien la variable es una instancia de la clase.
Pero......... quien va a meter la instancia de otra clase en una variable private ?

Otra cosa... si el constructor es privado... se podria heredar....... o estoy mal ?
__________________
Salu2!
  #8 (permalink)  
Antiguo 19/07/2011, 11:10
Avatar de GatorV
$this->role('moderador');
 
Fecha de Ingreso: mayo-2006
Ubicación: /home/ams/
Mensajes: 38.567
Antigüedad: 14 años, 1 mes
Puntos: 2135
Respuesta: Singleton: implementacion

Es más limpio si compruebas si la instancia es de la misma clase, es la idea del patrón, que te garantice una sola instancia de esa clase.

No, si es private no lo puedes heredar, de hecho el patrón singleton no se debe de heredar, ya que como lo indica el patrón, es para garantizar una instancia de esa clase.

Saludos.
  #9 (permalink)  
Antiguo 19/07/2011, 11:15
Avatar de Italico76  
Fecha de Ingreso: abril-2007
Mensajes: 3.303
Antigüedad: 13 años, 3 meses
Puntos: 292
Respuesta: Singleton: implementacion

A eso iva...

Si el constructor es private ... usar is_objet() pasa a ser valido
__________________
Salu2!
  #10 (permalink)  
Antiguo 19/07/2011, 11:21
Avatar de GatorV
$this->role('moderador');
 
Fecha de Ingreso: mayo-2006
Ubicación: /home/ams/
Mensajes: 38.567
Antigüedad: 14 años, 1 mes
Puntos: 2135
Respuesta: Singleton: implementacion

Pues no, porque que tal si en algún punto de tu clase cambia self::$_instance por otra cosa, tendrías un error:

Código PHP:
Ver original
  1. class Singleton
  2. {
  3.        private static $_instance = null;
  4.  
  5.        private function __construct(){}
  6.  
  7.        public static function getInstance()
  8.        {
  9.               if(!(self::$_instance instanceof self)) {
  10.                       self::$_instance = new self();
  11.               }
  12.  
  13.               return self::$_instance;
  14.        }
  15.  
  16.        private function __clone() {}
  17.  
  18.        public function hijackInstance()
  19.        {
  20.               self::$_instance = new stdClass();
  21.        }
  22. }
  23.  
  24. $instance = Singleton::getInstance();
  25. var_dump($instance);
  26. $instance->hijackInstance();
  27. var_dump($instance);

Corre ese código como esta, y reemplaza el chequeo por is_object y puedes ver donde tienes un problema.

La idea del patrón es que sea un punto único de entrada, digamos un constructor único por instancia.

Saludos.
  #11 (permalink)  
Antiguo 19/07/2011, 11:34
Avatar de masterpuppet
Software Craftsman
 
Fecha de Ingreso: enero-2008
Ubicación: Montevideo, Uruguay
Mensajes: 3.550
Antigüedad: 12 años, 5 meses
Puntos: 845
Respuesta: Singleton: implementacion

Si bien la idea es que haya una única instancia de una clase, el esqueleto del singleton es siempre el mismo, y puede ser una opción extender de una clase base a otras que quieras que sean Singleton's, esto dentro de la teoria, como dije antes no me agrada Signleton, solo que para lograrlo vas a depender de la versión de PHP, Late Static Binding esta disponible recien a partir de PHP 5.3+, y hay que hacer unos ajustes, algo asi:

Código PHP:
Ver original
  1. class Singleton
  2. {
  3.     protected static $_instance = null;
  4.  
  5.     private function __construct()
  6.     {}
  7.  
  8.     public static function getInstance()
  9.     {
  10.         if (null === static::$_instance) {
  11.             static::$_instance = new static;
  12.         }
  13.         return static::$_instance;
  14.     }
  15.  
  16.     private function __clone()
  17.     {}
  18. }
  19.  
  20. class SimpleSingleton extends Singleton
  21. {
  22.     protected static $_instance = null;
  23. }

Con respecto a la sintaxis, yo no veo nada extraño, a que le dices "horrible" ?
__________________
http://es.phptherightway.com/
thats us riders :)
  #12 (permalink)  
Antiguo 19/07/2011, 12:39
Avatar de Italico76  
Fecha de Ingreso: abril-2007
Mensajes: 3.303
Antigüedad: 13 años, 3 meses
Puntos: 292
Respuesta: Singleton: implementacion

"Horrible" es mi entendimiento

masterpuppet: gracias por todos tus valiosos comentarios y lo mismo para GatorV que siempre esta dispuesto a ayudar
__________________
Salu2!
  #13 (permalink)  
Antiguo 19/07/2011, 12:51
Avatar de jahepi
Colaborador
 
Fecha de Ingreso: diciembre-2004
Ubicación: Querétaro
Mensajes: 1.124
Antigüedad: 15 años, 7 meses
Puntos: 43
Respuesta: Singleton: implementacion

A modo off-topic, relacionado con lo que ha dicho masterpuppet.

Muchos consideran el patrón singleton un anti-patrón por que muchos caen en el error de tratar de emular el uso de las variables globales, lo cual en la OOP es algo que debemos evitar a toda costa, uno de los grandes problemas es la ocultación de las dependencias, por ejemplo, un método puede que utilice un variable singleton pero en la declaración no nos informa absolutamente nada de esa dependencia, tendríamos que inspeccionar el código para darnos cuenta, ahora imagina si la misma regla aplica no a una si no a cientos de clases, hace sumamente difícil depurar el código.

Otro punto importante es la reusabilidad, puede que queramos utilizar una clase en otro proyecto pero al no saber que depende de un singleton pues ya sabrás las consecuencias iníciales.

Utiliza singleton si es necesario, usa "la inyección de dependencias" en las clases que utilicen el singleton para evitar los dolores de cabeza antes mencionados.

Un saludo y suerte !
__________________
Una contraseña es como la ropa interior. No deberías dejarlas afuera a la vista de otras personas, deberías cambiarla regularmente, y ni se te ocurra prestarla a extraños.
  #14 (permalink)  
Antiguo 19/07/2011, 16:33
 
Fecha de Ingreso: agosto-2009
Mensajes: 247
Antigüedad: 10 años, 11 meses
Puntos: 10
Respuesta: Singleton: implementacion

Muy bueno lo de "la inyección de dependencias" .... !
__________________
The best powerful search engine for MSN messenger profiles I know is msn profile viewer. It's really good either if you have an e-mail address or not. Try it!

Etiquetas: implementacion, singleton
Atención: Estás leyendo un tema que no tiene actividad desde hace más de 6 MESES, te recomendamos abrir un Nuevo tema en lugar de responder al actual.
Respuesta

SíEste tema le ha gustado a 1 personas




La zona horaria es GMT -6. Ahora son las 10:28.