El patrón de diseño singleton tiene la intención de garantizar que una clase solo tenga una instancia y proporcionar un punto de acceso global a ella.
Cuando usamos Programacion Orientada a Objetos tenemos en cuenta que al crear una nueva instancia de una clase, se crean nuevos recursos para cada instancia, con el singleton es diferente, ya que solo existe una instancia.
Codigo de una clase normal
class MiClase { public function __construct(){ } public function hola(){ echo "Hola!"; } }
En una clase normal tenemos un constructor y tenemos los métodos públicos o privados, etc. Cada vez que creamos una instancia podemos acceder a los métodos desde la variable de instancia.
$ins1 = new MiClase(); $ins2 = new Miclase(); $ins1->hola(); $ins2->hola();
Y para cada instancia se crean recursos en la memoria, pero hay casos donde no es necesario crear mas recursos, por ejemplo al usar descriptores de archivos o conexiones a la base de datos.
Codigo de una clase Singleton
class MiClase { // Contenedor instancia de la clase private static $instance = NULL; // Constructor privado, previene la creación de objetos vía new private function __construct() { } // Clone no permitido private function __clone() { } // Método singleton public static function getInstance() { if (is_null(self::$instance)) { self::$instance = new Singleton(); } return self::$instance; } public void hola(){ echo "Hola"; } }
En una clase singleton tenemos lo siguiente:
- Tenemos una variable privada estática llamada instancia que solo puede usarse en la función publica estática getInstance()
- Hacemos el constructor privado para que solo pueda ser usado dentro de la misma clase.
- Evitamos la clonacion de objectos
- En la funcion getInstance() que seria nuestro acceso global o constructor hacemos lo siguiente:
- Primero verificamos si la variable $instance es nula
- Si la variable $instance es nula entonces creamos la instancia y la almacenamos dentro de $instance
- Si la variable $instance no es nula entonces devolvemos la variable $instance como instancia
Con esto logramos que la instancia solo se creara una vez y depues cuando $instance no sea null entonces se evitara crear mas instancias y con ello también evitar llamadas al constructor de la clase.
Ejemplo Practico
En el siguiente ejemplo demostramos el singleton usando una conexión a la base de datos, donde la conexión solo se ejecutara en el constructor.
class Connection { // Contenedor Instancia de la clase private static $instance = NULL; private $con = NULL; // Constructor privado, previene la creación de objetos vía new private function __construct() { $this->con = new mysqli("HOST","USER","PASSWORD","DATABASE"); } // Clone no permitido private function __clone() { } // Método singleton public static function getInstance() { if (is_null(self::$instance)) { self::$instance = new Singleton(); } return self::$instance; } public function query($sql){ return $this->con($query); } }
Al hacer que la conexion solo se ejecute en el constructor y teniendo la clase singleton evitamos que se creen mas conexiones a la base de datos, ya que solo necesitamos una conexion y cada vez que realicemos conexiones vamos a utilizar mas recursos.
Para hacer uso de este ejemplo hacemos lo siguiente:
$con1 = Connection::getInstance(); $quer = $con->query("select * from user"); // Otra forma seria $quer = Connection::getInstance()->query("select * from user");
Eso seria todo, a ustedes que les parece ?
me gusto mucho tu explicacion, despues de decenas de articulos hasta ahora la mejor que he encontrado 🙂
Me parece genial! Ahorro ahorro y ahorro.. gracias maestro
Exacto amigo, saludos