Pero al final, por muchos patrones de diseño que haya, con un sólo patrón de diseño se pueden arreglar "todos" los problemas, otra cosa es el camino que tengas que seguir para adaptar ese patrón a ese problema (o ese problema a ese patrón).
Por ejemplo, una conexión a la base de datos, hay gente que aplica el patrón Registry, otros Singleton, otros inyección de dependencias... y mientras resuelvan su problema concreto es suficiente.
Si no van a necesitar conectarse a dos bases de datos usarán un singleton por ejemplo, en vez de inyección de dependencias. Me podrás decir, pero si usas inyección de dependencias estás siendo previsor para el día que si necesites trabajar contra más de una base de datos, si, cierto, pero andar a pensar en el futuro si aun no has acabado el presente.... no necesariamente es bueno...
Bueno, tampoco pretendo crear discusión, al fin y al cabo este tipo de discusiones ya están más que manidas, simplemente quería saber si el código con el que estoy trasteando esta bien en cuanto a POO se refiere o si es una burrada (a pesar de que funciona).
Al final le he dado un par de vueltas a las clases que puse previamente y llegué a esto:
Código PHP:
<?php
abstract class Clase_Base
{
protected function __construct ()
{
echo '<p>Constructor Clase_Base</p>';
}
}
abstract class Clase_Base_Singleton extends Clase_Base
{
private static $Instancia = array();
private static $NInstancias = array();
private static $ModoSingleton = array();
protected function __construct ($Clase)
{
if (!isset(self::$ModoSingleton[$Clase]) || (isset(self::$ModoSingleton[$Clase]) && self::$ModoSingleton[$Clase] === FALSE))
{
self::$ModoSingleton[$Clase] = FALSE;
self::$NInstancias[$Clase] = 1;
echo '<p>Constructor Clase_Base_Singleton</p>';
parent::__construct();
}
else
{
echo "<p><b>Clase ya instanciada en modo singleton</b></p>";
}
}
public static function singleton($Clase)
{
if (!isset(self::$ModoSingleton[$Clase]))
{
echo '<p>Singleton</p>';
self::$Instancia[$Clase] = new $Clase;
self::$ModoSingleton[$Clase] = TRUE;
self::$NInstancias[$Clase] = 0;
}
if (isset(self::$ModoSingleton[$Clase]) && self::$ModoSingleton[$Clase] === TRUE)
{
self::$NInstancias[$Clase]++;
return self::$Instancia[$Clase];
}
else
{
echo '<p><b>Clase ya instanciada en modo no singleton</b></p>';
}
}
public function get_NInstancias($Clase) { echo '<p>NInstancia: ' . self::$NInstancias[$Clase] . '</p>'; }
}
class Mi_Clase extends Clase_Base_Singleton
{
public function __construct ()
{
echo '<p>Constructor Mi_Clase</p>';
parent::__construct('Mi_Clase');
}
}
class Mi_Clase2 extends Clase_Base_Singleton
{
public function __construct ()
{
echo '<p>Constructor Mi_Clase2</p>';
parent::__construct('Mi_Clase2');
}
}
echo '<p><b>Singleton</b></p>';
$Clase1 = Mi_Clase::singleton('Mi_Clase');
$Clase1->get_NInstancias('Mi_Clase');
echo '<p><b>Singleton</b></p>';
$Clase2 = Mi_Clase::singleton('Mi_Clase');
$Clase2->get_NInstancias('Mi_Clase');
echo '<p><b>Singleton</b></p>';
$Clase3 = Mi_Clase::singleton('Mi_Clase');
$Clase3->get_NInstancias('Mi_Clase');
echo '<p><b>Normal</b></p>';
$Clase4 = new Mi_Clase;
echo '<p><b>Normal</b></p>';
$Clase5 = new Mi_Clase2;
$Clase5->get_NInstancias('Mi_Clase2');
echo '<p><b>Normal</b></p>';
$Clase6 = new Mi_Clase2;
$Clase6->get_NInstancias('Mi_Clase2');
echo '<p><b>Normal</b></p>';
$Clase7 = new Mi_Clase2;
$Clase7->get_NInstancias('Mi_Clase2');
echo '<p><b>Singleton</b></p>';
$Clase8 = Mi_Clase::singleton('Mi_Clase2');
?>
Que produce como salida
Código HTML:
Singleton
Singleton
Constructor Mi_Clase
Constructor Clase_Base_Singleton
Constructor Clase_Base
NInstancia: 1
Singleton
NInstancia: 2
Singleton
NInstancia: 3
Normal
Constructor Mi_Clase
Clase ya instanciada en modo singleton
Normal
Constructor Mi_Clase2
Constructor Clase_Base_Singleton
Constructor Clase_Base
NInstancia: 1
Normal
Constructor Mi_Clase2
Constructor Clase_Base_Singleton
Constructor Clase_Base
NInstancia: 1
Normal
Constructor Mi_Clase2
Constructor Clase_Base_Singleton
Constructor Clase_Base
NInstancia: 1
Singleton
Clase ya instanciada en modo no singleton
De esta forma consigo que cualquier clase que cree pueda ser inicializada en modo singleton o no según me apetezca.