2010-04-06 24 views
5

i utiliza para crear una instancia de una clase Singleton así:La extensión de una clase Singleton

$Singleton = SingletonClassName::GetInstance(); 

y para la clase Singleton no:

$NonSingleton = new NonSingletonClassName; 

creo que no debe diferenciar la forma de crear una instancia de una clase si esto es un singleton o no. si miro en la percepción de otra clase, no me importa si la clase necesitamos una clase singleton o no. entonces, todavía no me siento cómodo con la forma en que php trata una clase de singleton. creo y siempre quiero escribir:

$Singleton = new SingletonClassName; 

solo otra clase no singleton, ¿hay alguna solución a este problema?

+1

Esto no es una pregunta: es usted quien se queja de que no le gusta cómo se realiza un patrón. -1 –

+1

Esta es una pregunta muy justificada. +1 porque -1 no es: P – Leo

+2

¿No usas PHP? – Kevin

Respuesta

2

yo no lo recomendaría como sería hacer que el código mucho más difícil de entender (La gente piensa nuevos medios un objeto totalmente nuevo). Pero entonces no recobré el uso de Singletons.

La idea básica de este código es que hay un contenedor alrededor de un singleton. Todas las funciones y variables a las que se accede a través de ese contenedor realmente afectan al singleton. No es perfecto, ya que el código de abajo no implementa una gran cantidad de métodos mágicos e interfaces SPL pero se puede añadir en caso necesario

Código

/** 
* Superclass for a wrapper around a singleton implementation 
* 
* This class provides all the required functionality and avoids having to copy and 
* paste code for multiple singletons. 
*/ 
class SingletonWrapper{ 
    private $_instance; 
    /** 
    * Ensures only derived classes can be constructed 
    * 
    * @param string $c The name of the singleton implementation class 
    */ 
    protected function __construct($c){ 
     $this->_instance = &call_user_func(array($c, 'getInstance')); 
    } 
    public function __call($name, $args){ 
     call_user_func_array(array($this->_instance, $name), $args); 
    } 
    public function __get($name){ 
     return $this->_instance->{$name}; 
    } 
    public function __set($name, $value){ 
     $this->_instance->{$name} = $value; 
    } 
} 

/** 
* A test singleton implementation. This shouldn't be constructed and getInstance shouldn't 
* be used except by the MySingleton wrapper class. 
*/ 
class MySingletonImpl{ 
    private static $instance = null; 
    public function &getInstance(){ 
     if (self::$instance === null){ 
      self::$instance = new self(); 
     } 
     return self::$instance; 
    } 

    //test functions 
    public $foo = 1; 
    public function bar(){ 
     static $var = 1; 
     echo $var++; 
    } 
} 

/** 
* A wrapper around the MySingletonImpl class 
*/ 
class MySingleton extends SingletonWrapper{ 
    public function __construct(){ 
     parent::__construct('MySingletonImpl'); 
    } 
} 

Ejemplos

$s1 = new MySingleton(); 
echo $s1->foo; //1 
$s1->foo = 2; 

$s2 = new MySingleton(); 
echo $s2->foo; //2 

$s1->bar(); //1 
$s2->bar(); //2 
+0

wow, eso está bien. muchas gracias ! – cakyus

3

Es mejor que sea al revés - proporcionar un factory-method para los no únicos, y obtener instancias de las mismas usando:

$NonSingleton = NonSingletonClassName::createInstance(); 

Esta es una práctica recomendada para Java (en Effective Java), pero se aplica a la mayoría de los lenguajes orientados a objetos.

1

No puede crear un Singleton de la misma manera que una instancia de clase normal. new siempre devolverá una nueva instancia, por lo tanto, debe tener el constructor no público y, por lo tanto, debe tener un medio diferente para llamarlo desde dentro de la clase.

Puede tener métodos de fábrica en todas las clases, p. siempre haga getInstance() como se muestra en otra respuesta. Otra opción sería usar un Service Locator y Dependency Injection Framework que sepa si devolver qué.

1

Según lo que new palabra clave significa que todo lo que desea es irrelevante. new crea nueva instancia de la clase, es por eso que el nombre nueva :-)

+0

ja, ja ... tienes toda la razón :-) – cakyus

Cuestiones relacionadas