Singleton es un patrón de diseño, que tiene como propósito asegurar que solo se pueda crear una instancia de la clase y proporcionar un punto global de acceso a ella.
Código :
<?php class Singleton { private static $instancia; private $contador; private function __construct() { echo "He creado un " . __CLASS__ . "\n"; $this->contador =0; } public static function getInstance() { if ( !self::$instancia instanceof self) { self::$instancia = new self; } return self::$instancia; } public function incrementar() { return ++$this->contador; } public function disminuir() { return --$this->contador; } } ?>
Código :
<?php $instancia = Singleton::getInstance(); echo "instancia (incrementar): " . $instancia->incrementar() . "\n"; echo "instancia (incrementar): " .$instancia->incrementar() . "\n"; echo "instancia (incrementar): " .$instancia->incrementar() . "\n"; $otraInstancia = Singleton::getInstance(); echo "otraInstancia (disminuir): " .$otraInstancia->disminuir() . "\n"; echo "otraInstancia (incrementar): " .$otraInstancia->incrementar() . "\n"; ?>
Salida:
En php en posible clonar objetos, lo que permitiría crear otra instancia de nuestro Singleton.
Código :
<?php $instancia = Singleton::getInstance(); echo "Instancia quedo en: " . $instancia->incrementar() . "\n"; $miClon = clone($instancia); echo "Clon: ". $miClon->incrementar() . "\n"; echo "Clon: ". $miClon->incrementar() . "\n"; echo "Clon: ". $miClon->incrementar() . "\n"; echo "Instancia(incrementar-1) seguia en: " . ($instancia->incrementar()-1) . "\n"; ?>
Salida:
Código :
<?php class Singleton { //codigo previo public function __clone() { trigger_error("Operación Invalida: No puedes clonar una instancia de ". get_class($this) ." class.", E_USER_ERROR ); } } ?>
Ahora nuestra salida sería:
Con la función serialize podemos almacenar una representación apta de una variable (una instancia, es una variable a fin de cuentas), sin perder su tipo ni estructura. Y, con unserialize (deserializacion) podemos obtener esa "representación apta" de la variable, accediendo a ella como se si tratara de un clon.
Demostración:
Código :
<?php $instancia = Singleton::getInstance(); echo "Instancia quedo en: " . $instancia->incrementar() . "\n"; $serializado = serialize($instancia); $nuevaInstancia = unserialize($serializado); echo "Deserializado: " . $nuevaInstancia->incrementar() . "\n"; echo "Deserializado: " . $nuevaInstancia->incrementar() . "\n"; echo "Deserializado: " . $nuevaInstancia->incrementar() . "\n"; echo "Instancia sigue en: " . ($instancia->incrementar()-1) . "\n"; ?>
Salida:
Código :
<?php class Singleton { //codigo previo public function __wakeup() { trigger_error("No puedes deserializar una instancia de ". get_class($this) ." class."); } } ?>
Ahora nuestra salida sería:
Con el apoyo de estos métodos mágicos nos aseguramos de que no se genere más de una instancia de Singleton, cumpliendo así con el objetivo principal de Singleton que es el de mantener una instancia.
Nota Final:
Sé que el ejemplo no es de lo mejor para demostrar y quizás te cuesta ver lo que es el patrón de diseño Singleton. En una próxima entrega, explicaré otro tema donde usaré el patrón de diseño Singleton.
Singleton es un patrón de diseño, y como tal, la lógica e implementación de los patrones está divulgada en diversos artículos, lenguajes y versiones. Por lo que, cualquier código en este artículo -a menos que se indique lo contrario- solo se presenta con propósito educativo y ni el autor del articulo ni Cristalab tienen ni pretenden tomar propiedad intelectual sobre ellos.
Si tienes alguna pregunta de este tutorial; puedes hacerla aqui en los foros