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.