Bien, me voy a enfocar a explicar cómo implementarlo en php, el cual con esta ténica es soportada a partir de php 5.0+ pues en versiones anteriores el manejo de ciertos métodos mágicos no funcionaría.
<?php
/**
* Description of Singleton
*
* @author Ultiminio Ramos
*/
class Singleton
{
private static $instancia;
private $_contador;
/**
* Declaramos private el método constructor, para evitar acceder a él cada vez
* que se realiza la instanciación de esta clase
*/
private function __construct()
{
echo 'Se ha instanciado una clase (<code style="color: blue; font-weight: bolder;">' . __CLASS__ . "</code>)< br/>";
$this->_contador = 0;
}
/**
* Punto global de acceso a la clase, pues el método constructor lo hemos
* declarado como private para asegurarnos de que no se puede acceder a él
* sino solamente por medio de este método llamado getInstance()
*
* @return object
*/
public static function getInstance()
{
if (!self::$instancia instanceof self) {
self::$instancia = new self;
}
return self::$instancia;
}
/**
* Método público que ya es accesible desde un objeto instanciado
*/
public function incrementar()
{
return ++$this->_contador;
}
/**
* Método público que ya es accesible desde un objeto instanciado
*/
public function disminuir()
{
return --$this->_contador;
}
/**
* Método mágico que nos permite gestionar la clonación y evitar que se rompa
* el patrón singleton
*/
public function __clone()
{
$error_msg = 'No se permite la clonación dentro del patrón singleton';
$error_msg.= '(<code style="color: blue;">' . get_class($this) . '</code>)';
//trigger_error($error_msg, E_USER_NOTICE); # mandamos un mensaje, pero la ejecución no se interrumpe
trigger_error($error_msg, E_USER_ERROR); # interrumpimos la ejecución
}
/**
* Método mágico para gestionar la serialización y por consiguiente
* evitar romper el patrón singleton
*/
public function __wakeup()
{
$error_msg = 'No se permite la serialización dentro del patrón singleton';
$error_msg.= '(<code style="color: blue;">' . get_class($this) . '</code>)';
trigger_error($error_msg, E_USER_ERROR); # interrumpimos la ejecución
}
}
Ahora, es momento de probar nuestro patrón de diseño.
<!DOCTYPE html>
<html>
<head>
<meta http-equiv="Content-Type" content="text/html; charset=UTF-8">
<title>Probar el patrón Singleton en PHP 5.0+</title>
</head>
<body>
<?php
include_once 'app/test_singleton/model/Singleton.php';
$br = '< br/>';
$instancia = Singleton::getInstance();
echo '<pre>';
echo 'instancia(++$i) = ' . $instancia->incrementar() . $br;
echo 'instancia(++$i) = ' . $instancia->incrementar() . $br;
echo 'instancia(++$i) = ' . $instancia->incrementar() . $br;
echo 'instancia(++$i) = ' . $instancia->incrementar() . $br;
echo 'instancia(++$i) = ' . ($instancia->incrementar()) . $br;
echo '<hr/>';
# probar la clonación como técnica para romper el patrón singleton
$clone = clone($instancia);
echo 'clone_instancia(--$i) = ' . $clone->disminuir() . $br;
echo 'clone_instancia(--$i) = ' . $clone->disminuir() . $br;
echo 'clone_instancia(++$i) = ' . $clone->incrementar() . $br;
echo 'clone_instancia(++$i) = ' . $clone->incrementar() . $br;
echo 'clone_instancia(++$i) = ' . $clone->incrementar() . $br;
echo 'clone_instancia(++$i) = ' . $clone->incrementar() . $br;
echo 'clone_instancia(++$i) = ' . $clone->incrementar() . $br;
echo 'clone_instancia(++$i) = ' . $clone->incrementar() . $br;
echo 'clone_instancia(++$i) = ' . $clone->incrementar() . $br;
# probar la serialización/deserialización como técnica para romper el patrón singleton
$serializado = serialize($instancia);
$unserializa = unserialize($serializado);
echo '$unserializa(++$i) = ' . $unserializa->incrementar() . $br;
echo '$unserializa(++$i) = ' . $unserializa->incrementar() . $br;
echo '$unserializa(++$i) = ' . $unserializa->incrementar() . $br;
echo '$unserializa(++$i) = ' . $unserializa->incrementar() . $br;
# comprobación
echo '.' . $br;
echo '.' . $br;
echo '.' . $br;
echo 'instancia(++$i) = ' . $instancia->incrementar() . $br;
echo '</pre>';
?>
</body>
</html>
Espero les sirva el ejemplo, y como dijeran los gringos: "happy conding"
No hay comentarios:
Publicar un comentario