Inicio | Pedro Santana |  RSS  Mi tumblelog  Mis photos  Mi CV

 

Patrones en PHP5 : Singleton

Como Jorge mencionó en su último post, andamos re-diseñando la arquitectura de gelato cms, para en un par de versiones mudarlo completamente a PHP5 para obtener ventaja de su poderoso motor de OOP y poder hacer un mejor uso de los patrones de diseño.

Por lo que comenzaré con una serie de posts sobre como implementar patrones de diseño con PHP5 y un par de ejemplos un poco más adelante de como aplicarlos en “la vida real” de nuestros proyectos.

El primer patrón con el que iniciaré es el patrón Singleton, el cual considero como la base de la implementación exitosa de muchos patrones.

La teoría nos dice lo siguiente:

El patrón de diseño Singleton (instancia única) está diseñado para restringir la creación de objetos pertenecientes a una clase o el valor de un tipo a un único objeto.

Su intención consiste en garantizar que una clase sólo tenga una instancia y proporcionar un punto de acceso global a ella.

Por lo que al usar el patrón Singleton nos aseguramos que SOLO tendremos una misma instancia de nuestra clase.

¿Cómo hacerlo con PHP5?

  1. < ?php
  2. class Singleton {
  3.  
  4.     // Una propiedad para tener la instancia de la clase
  5.     private static $instancia;   
  6.  
  7.     // Desde aqui se obtiene la instancia OJO con el static
  8.     public static function getInstance () {
  9.         if (!isset(self::$instancia)) {
  10.             $obj = __CLASS__;
  11.             self::$instancia = new $obj;
  12.         }
  13.         return self::$instancia;
  14.     }
  15.  
  16.     // Se crean los metodos requeridos
  17.     public function accion() {
  18.         echo "Objeto unico";
  19.     }   
  20.  
  21.     // Privado se previene la creacion via new
  22.     private function __construct() { }   
  23.  
  24.     // Para evitar la clonacion de este objeto
  25.     private function __clone() {
  26.         throw new Exception(‘No se permite clonar’);
  27.     }
  28. }
  29. ?>

Y para utilizarlo:

  1. < ?php
  2. include("singleton.php");
  3. $prueba = Singleton::getInstance();
  4. $prueba->accion();
  5. ?>

Nos leemos en la siguiente entrega :P

10 comentarios en “Patrones en PHP5 : Singleton”

 

marcoss

No me convence mucho como instancias, creo que esto:

public static function getInstance () {
if (!isset(self::$instancia)) {
$obj = __CLASS__;
self::$instancia = new $obj;
}
return self::$instancia;
}

podría simplificarse en:

public static function getInstance () {
self::$instancia =& $this;
}

Vos que sos mas conocedor, fijate si tiene alguna desventaja que no estoy viendo.

pecesama

marcoss muy buena pregunta, trataré de responder lo mejor que pueda, pero se me pude ir algo, tú dime si se me esta escapando algo ahora a mi :)

Creo que hay un poco de confusión, el & se usaba en PHP4 para pasar variables u objetos por referencia, pero en PHP5 ya todo es por referencia, por lo que el & deja de ser útil, y me parece que usar el self::instancia seria mezclarlo, más bien algo así:

$instancia =& new $class;

En la forma en que me muestras el método getInstance no funcionaría correctamente ya que no hay validaciones de que si no existe previamente el objeto cree uno nuevo y el método debería llevar un & en el nombre, quedaría algo así en PHP4 ese método:


function &getInstance ($class) {
static $instancia;
if (!isset( $instancia )) {
$instancia =& new $class;
}
return $instancia;
}

Y el método en PHP5 se podría simplificar de la siguiente manera:


public static function getInstance () {
if (!isset(self::$instancia)) {
self::$instancia = new self();
}
return self::$instancia;
}

marcoss

Ya me di cuenta donde estaba mi error, lo peor es que creo que lo probe antes de comentar y se ve que funcionaba… pero ahora veo que no tiene sentido, en fin, eso pasa por dejar un comentario cuando debería estar durmiendo :P

La segunda opción está mas clara igual, “self::$instancia = new self();”

jhon

bueno realmente probe el ejemplo y funciono bien el problema surge cuando incluyo “singleton” el la clase A y tambien lo hago en B;
hasta hay todo bien pero cuando trato de incluir B en A me dice que no puedo redeclarar “singleton”..mi pregunta de que manera puedo hacerlo pues necesito manejar las clase…grasias

allende

Muy claro el ejemplo, solo tengo una duda

Si (corrigeme si me equivoco por favor o aclaramelo) “__CLASS__” regresa un string con el nombre de la clase, como es posible que funcione en la siguiente linea la variable $obj.

$obj = __CLASS__;
self::$instancia = new $obj;

Es decir si hiciera:
self::$instancia = new “Singleton”;

No funciona (salvo que quite las comillas), me deja un poco perdido eso, ademas de que usar __CLASS__ después del new tampoco me funciona:
self::$instancia = new __CLASS__;

Supongo que usar “self” o “Singleton” (sin comillas) es equivalente al uso de “$obj = __CLASS__” y luego:
self::$instancia = new $obj;

Un saludo y gracias.

 

Deja un comentario