Patrón Singleton
🧠 ¿Qué es el patrón Singleton?
El patrón Singleton es un patrón de diseño creacional que garantiza que una clase tenga una única instancia y proporciona un punto de acceso global a ella. Es útil cuando necesitas exactamente un objeto para coordinar acciones en todo el sistema (por ejemplo, una conexión a base de datos, un logger, una configuración global, etc.).
🧙♂️ Ejemplo: El Anillo Único (Singleton)
<?php
class AnilloUnico {
// Propiedad estática para almacenar la instancia única
private static $instancia = null;
private $portador = null;
// Constructor privado: nadie puede forjar otro Anillo Único
private function __construct() {
echo "El Anillo Único ha sido forjado en los fuegos de Mordor.\n";
}
// Método estático para obtener el Anillo Único
public static function obtenerAnillo() {
if (self::$instancia === null) {
self::$instancia = new self();
}
return self::$instancia;
}
// Método para reclamar el Anillo
public function reclamar($nombre) {
$this->portador = $nombre;
echo "$nombre ahora es el portador del Anillo Único.\n";
}
// Saber quién es el portador actual
public function verPortador() {
return $this->portador ?? "Nadie";
}
}
// Frodo intenta obtener el Anillo
$anillo1 = AnilloUnico::obtenerAnillo();
$anillo1->reclamar("Frodo");
// Gollum también lo quiere
$anillo2 = AnilloUnico::obtenerAnillo();
$anillo2->reclamar("Gollum");
// Ambos acceden al mismo Anillo
echo "El portador actual es: " . $anillo1->verPortador() . "\n";
echo "¿Ambos objetos son el mismo? " . ($anillo1 === $anillo2 ? "Sí" : "No") . "\n";Salida Esperada:
El Anillo Único ha sido forjado en los fuegos de Mordor.
Frodo ahora es el portador del Anillo Único.
Gollum ahora es el portador del Anillo Único.
El portador actual es: Gollum
¿Ambos objetos son el mismo? SíExplicación:
- Solo puede existir un Anillo Único: la clase solo permite una instancia.
- Todos los personajes acceden al mismo objeto: aunque diferentes personajes reclamen el anillo, siempre es el mismo objeto.
- El portador cambia, pero el Anillo es único: puedes ver quién es el portador actual, pero nunca habrá dos Anillos Únicos.
📄 Ejemplo real: Singleton para conexión a base de datos
<?php
class ConexionBD {
// Propiedad estática para almacenar la instancia única
private static $instancia = null;
private $conexion;
// Configuración de la base de datos
private $host = 'localhost';
private $db = 'mi_base_de_datos';
private $usuario = 'usuario';
private $contrasena = 'contrasena';
// Constructor privado
private function __construct() {
try {
$this->conexion = new PDO(
"mysql:host={$this->host};dbname={$this->db};charset=utf8",
$this->usuario,
$this->contrasena
);
$this->conexion->setAttribute(PDO::ATTR_ERRMODE, PDO::ERRMODE_EXCEPTION);
} catch (PDOException $e) {
die("Error de conexión: " . $e->getMessage());
}
}
// Método estático para obtener la instancia única
public static function getInstancia() {
if (self::$instancia === null) {
self::$instancia = new self();
}
return self::$instancia;
}
// Método para obtener el objeto PDO
public function getConexion() {
return $this->conexion;
}
}
// Uso del Singleton para la base de datos
$db = ConexionBD::getInstancia()->getConexion();
// Ejemplo de consulta
$stmt = $db->query("SELECT * FROM usuarios");
$usuarios = $stmt->fetchAll(PDO::FETCH_ASSOC);
print_r($usuarios);
?>📝 Resumen de uso y ventajas
- ¿Cuándo usarlo? Cuando necesitas una única instancia de una clase en toda la aplicación (conexión a BD, logger, configuración, etc.).
- Ventajas: Control centralizado, ahorro de recursos, acceso global.
- Desventajas: Puede dificultar pruebas unitarias y acoplar el código si se abusa.
Eso ha sido todo por hoy.
Nos vemos en el próximo patrón... o en la próxima frikada que se me ocurra para explicarlo 👾.