El patrón singleton en PHP

El singleton se encuentra entre los primeros patrones de diseño que aprenden la mayoría de los desarrolladores. El objetivo de este patrón de diseño es limitar el número de instancias de clase a solo una. Lo que esto significa es que usar la palabra clave new en una clase siempre devolverá una misma instancia de objeto.

Este es un concepto poderoso que nos permite implementar todo tipo de objetos para toda la aplicación, como registradores, mailers, registros y otros bits de funcionalidad que podemos querer que actúen como singletons. Sin embargo, como veremos pronto, evitaremos la palabra clave new por completo y crearemos una instancia de un objeto mediante el método de clase estática.

El siguiente ejemplo demuestra una posible implementación de patrón singleton:

<?php
class Logger
{
private static $instance;
const TYPE_ERROR = 'error';
const TYPE_WARNING = 'warning';
const TYPE_NOTICE = 'notice';
protected function __construct()
{
// empty?!
}
private function __clone()
{
// empty?!
}
private function __wakeup()
{
// empty?!
}
public static function getInstance()
{
if (!isset(self::$instance)) {
// late static binding
self::$instance = new self;
}
return self::$instance;
}
public function log($type, $message)
{
return sprintf('Logging %s: %s', $type, $message);
}
}
// Client use
echo Logger::getInstance()->log(Logger::TYPE_NOTICE, 'test');

La clase Logger usa el miembro estático $instance para mantener una instancia de uno mismo, según la implementación del método getInstance(). Definimos __construct como protegido para evitar la creación de una nueva instancia a través del operador new. El método __clone() se definió como privado para evitar la clonación de instancias a través del operador clone. Del mismo modo, el método __wakeup() también se definió como privado, para evitar que la instancia no se serialice a través de la función unserialize(). Estas pocas restricciones simples hacen que una clase actúe como un singleton. Para obtener una instancia, todo lo que se necesita está llamando al método de clase getInstance().

Comparte