Ver Mensaje Individual
  #8 (permalink)  
Antiguo 11/05/2012, 18:31
Avatar de Ronin46
Ronin46
 
Fecha de Ingreso: junio-2009
Mensajes: 398
Antigüedad: 15 años, 4 meses
Puntos: 8
Respuesta: Clase que admite crear varias instancias o sólo una (patrón Singleton)

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.
__________________
http://www.controldegastos.com, acepto sugerencias para el sitio.
Repetir conmingo: "tengo que dedicar más tiempo a gozar de placer"