miércoles, 2 de marzo de 2011

Singleton en PHP

Entre los patrones de diseño de programación, se encuentra el Singleton, consistente en pocas palabras en restringir la creación de objetos de una clase a una única instancia, que será la que se utilice en todo el resto del código.

Los requisitos para este patrón son dos:
  • Un único punto de acceso a la variable única o singleton, accesible desde todo el resto del código.
  • Constructor privado para que sólo la propia clase sea capaz de manejar la creación de si misma.

Hay aspectos avanzados en todo este patrón que no voy a tratar aquí, simplemente voy a contar una implementación básica y como pie de post mencionaré los otros aspectos.

Para crear un constructor privado en PHP:
private function __construct(){}

La clase tendrá una instancia de sí misma, privada y estática:
private static $instance

Y existirá un método para acceder a esta variable y que en caso de no existir, se creará. Este método será público para que sea accesible desde todos sitios y estático, pues en un principio no contaremos con ninguna instancia de la variable.
public static function getInstance(){
  if(self::$instance == NULL){
   self::$instance = new Singleton();
  }
  return self::$instance;
}

Poniendo todo junto, quedaría algo así:

class Singleton{

  private static $instance;

  private function __construct(){}

  public static function getInstance(){
  if(self::$instance == NULL){
    self::$instance = new Singleton();
  }
  return self::$instance;
}

  public function test(){
    echo "Cualquier cosa";
  }
}


Y para hacer uso de ello, sería de la siguiente manera:
Singleton::getInstance()->test();


Los aspectos más avanzados que decía que hay que tener en cuenta son la clonación y la serialización: todavía sería posible crear otras instancias del objeto Singleton mediante una clonación o serialización/deserialización. Para controlar esto se debe limitar el uso del método __clone y __wakeup lanzando un error en caso de que sean llamados