Aquí venimos de nuevo con un nuevo patrón de diseño, el denominado singleton. Este patrón nos servirá para cuando queremos que un objeto tenga una sola y única instancia en toda la aplicación, como por ejemplo al conexión a la base de datos.
La conexión a bases de datos consume muchos recursos del servidor, por lo que nos interesa, conectar una sola vez y realizar todas las consultas necesarias, además de esta forma, nos evitamos tener que crear múltiples objetos que también hacen que la aplicación ocupe más memoria.
A continuación podéis ver la estructura básica de un singleton y después lo explicaremos detalladamente.
/**
* Objeto del cual deseamos tener una sola instancia
* en toda la aplicación.
*/
class mi_objeto
{
/**
* Aquí se almacenará la única instancia existente
* del propio objeto.
*
* @var mi_objeto
*/
private static $instancia;
/**
* Constructor para la creación de una instancia
* del objeto.
*/
private function __construct(){}
/**
* Método que siempre devuelve la misma instancia
* del objeto.
*/
public static function getInstance()
{
if ( !self::$instancia )
{
self::$instancia = new self;
}
return self::$instancia;
}
}
La primera parte y fundamental del código es la variable $instancia.
private static $instancia;
Esta variable almacenará la única instancia disponible en toda la aplicación. Esta variable es estática, ya que debe estar siempre accesible. Si no sabéis que es o para que sirve una variable estática, os recomiendo ver los ejemplos disponibles en la documentación oficial de php.
Más adelante nos encontramos con algo que al principio parece extraño y es que el constructor de la clase es privado. Como hemos dicho solo queremos una instancia en toda la aplicación y es por eso que el constructor es privado, para que nadie pueda realizar por desconocimiento o despiste algo como
Más adelante nos encontramos con algo que al principio parece extraño y es que el constructor de la clase es privado. Como hemos dicho solo queremos una instancia en toda la aplicación y es por eso que el constructor es privado, para que nadie pueda realizar por desconocimiento o despiste algo como
$variable = new mi_objeto();
ya que al ser el constructor privado, esto lanzaría un error en la aplicación y evitaría la creación descontrolada de objetos.
Llegados a este punto muchos se preguntarán como se hace entonces para poder crear una un objeto, teniendo el operador new bloqueado. Pues la respuesta es sencilla como ejecutar el método getInstance.
$obj = mi_objeto::getInstance();
Como puede verse en el código del método getInstance, lo que hace es primero que todo comprobar si el objeto ha sido creado anteriormente y en caso de que no haya sido creado anteriormente lo crea y lo devuelve. A partir de este momento, todas las veces que queramos obtener un objeto de la clase mi_objeto, ya no se devolverá una nueva instancia, si no que se obtendrá la generada por primera vez.
A continuación dejo un ejemplo práctico de una clase singleton, con un ejemplo de su funcionamiento. Probad a jugar un poco con ella y pensar posibles usos.
/**
* Objeto del cual deseamos tener una sola instancia
* en toda la aplicación.
*/
class mi_objeto
{
/**
* Aquí se almacenará la única instancia existente
* del propio objeto.
*
* @var mi_objeto
*/
private static $instancia;
/**
* Variable para almacenar un número
*/
public $numero;
/**
* Constructor para la creación de una instancia
* del objeto.
*/
private function __construct(){}
/**
* Método que siempre devuelve la misma instancia
* del objeto.
*/
public static function getInstance()
{
if ( !self::$instancia )
{
self::$instancia = new self;
}
return self::$instancia;
}
}
//Creo un objeto y le asigno un numero
$var = mi_objeto::getInstance();
$var->numero = 23;
//Elimino el contenido de la varible.
$var = null;
//Vuelvo a obtener una instancia del objeto.
//Al ser un singleton lo que se obtendrá es la
//misma instancia que estaba en $var
$nueva_var = mi_objeto::getInstance();
//Imprimirá el número 23
echo $nueva_var->numero;
Os dejo tanto el código base del singleton como del ejemplo para su descarga.

