2009-06-29 27 views
7

que tienen una clase con una función de fábrica de patrón en ella:crear instancias de clases hijas de la clase padre (PHP)

abstract class ParentObj { 
    public function __construct(){ ... } 
    public static function factory(){ 
     //returns new instance 
    } 
} 

que necesitan los niños para ser capaz de llamar a la función fábrica y devolver una instancia de la vocación clase: $child = Child::factory(); y preferiblemente sin anular la función de fábrica en la clase secundaria.

He intentado varias formas diferentes de lograr esto en vano. Preferiría mantenerme alejado de las soluciones que usan la reflexión, como __CLASS__.

(estoy usando PHP 5.2.5 si importa)

Respuesta

10

Si se puede actualizar a PHP 5.3 (released 30-Jun-2009), echa un vistazo a late static binding, que podría proporcionar una solución:

abstract class ParentObj { 
    public function __construct(){} 
    public static function factory(){ 

     //use php5.3 late static binding features: 
     $class=get_called_class(); 
     return new $class; 
    } 
} 


class ChildObj extends ParentObj{ 

    function foo(){ 
     echo "Hello world\n"; 
    } 

} 


$child=ChildObj::factory(); 
$child->foo(); 
+0

estoy jugando con RC4 en el minuto así que voy a tratar algo de código en breve si nadie más pasos en el ínterin ... –

+0

LSB parece ser la mejor solución que puedo encontrar por mi cuenta. Hasta que actualice, lo mejor que se me ocurre es pasar el nombre del niño a fábrica() o definir el nombre como propiedad y tomarlo de fábrica() –

+0

Según el manual de PHP, hay una función llamada ' get_called_class() 'que funciona como' __CLASS__' http://us.php.net/manual/en/function.get-called-class.php –

0

En mi humilde opinión, lo que estás tratando de hacer no tiene sentido.

Un patrón de la fábrica sería el siguiente:

abstract class Human {} 

class Child extends Human {} 
class Fool extends Human {} 

class HumanFactory 
{ 
    public static function get($token) 
    { 
     switch ($token) 
     { 
      case 'Kid' : return new Child(); 
      case 'King': return new Fool(); 
      default : throw new Exception('Not supported'); 
     } 
    } 
} 

$child = HumanFactory::get('Kid'); 
+0

Bueno, eso es un patrón de fábrica en toda regla. Simplemente quise decir un método estático para eludir el operador 'new' y para proporcionar legibilidad y encadenamiento a clases secundarias. –

+0

¿por qué quiere omitir el nuevo operador? –

+1

para usar su ejemplo, el nuevo Child() -> foo() no funciona. al agregar el método "fábrica" ​​(como lo uso), puede hacer Child :: factory() -> foo() -> bar(), que es más legible (en mi humilde opinión) que dividirlo en unas pocas líneas. Supongo que es una cuestión de opinión, y para ser justos, su implementación de una fábrica es útil. Simplemente no es lo que estoy buscando. –

Cuestiones relacionadas