2009-06-29 17 views
7

Mam klasy z funkcją fabrycznie wzorca w nim:instancji klasy dziecko od klasy nadrzędnej (PHP)

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

muszę dzieci, aby móc wywołać funkcję fabryki i powrócić instancję powołania klasa: $child = Child::factory(); i najlepiej bez nadpisywania funkcji fabrycznej w klasie potomnej.

Próbowałem różnych sposobów osiągnięcia tego bez skutku. Wolałbym trzymać się z daleka od rozwiązań wykorzystujących odbicie, takich jak __CLASS__.

(używam PHP 5.2.5 jeśli ma to znaczenie)

Odpowiedz

10

Jeśli można uaktualnić do PHP 5.3 (released 30-Jun-2009), sprawdź late static binding, które mogłyby stanowić rozwiązanie:

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

gram z RC4 na minutę więc spróbuję trochę kodu wkrótce, jeśli nikt inny nie podchodzi w międzyczasie ... –

+0

LSB wydaje być najlepszym rozwiązaniem, które mogę znaleźć na własną rękę. Do czasu aktualizacji, najlepsze, co mogę wymyślić, to przekazać nazwę dziecka do fabryki() lub zdefiniować nazwę jako właściwość i pobrać ją z fabryki() –

+0

Zgodnie z podręcznikiem PHP, istnieje funkcja o nazwie ' get_called_class() 'działa jak' __CLASS__' http://us.php.net/manual/en/function.get-called-class.php –

0

W moim skromna opinia, co próbujesz zrobić, nie ma sensu.

Wzór fabryka będzie działać tak:

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

Cóż, to w pełni rozwinięty wzór fabryczny. Po prostu oznaczałem statyczną metodę ominięcia operatora 'new' oraz zapewnienia czytelności i powiązania klas potomnych. –

+0

dlaczego chcesz ominąć nowego operatora? –

+1

, aby użyć twojego przykładu, nowe Dziecko() -> foo() nie działa. dodając metodę "fabryczną" (jak ja to używam), możesz zrobić Child :: factory() -> foo() -> bar(), która jest bardziej czytelna (IMHO) niż rozbicie go na kilka linii. Sądzę, że to kwestia opinii i aby być uczciwym, wasza implementacja fabryki jest przydatna. Po prostu nie za to, czego szukam. –

Powiązane problemy