2012-12-20 13 views
7

Pracuję nad usługą, do której wtryskuje się obiekt Logger, ale mogę mieć 2 różne rodzaje rejestratorów, planuję mieć rejestrator syslog i program rejestrujący komunikaty kolejki. czy to możliwe?Czy jest możliwe zdefiniowanie metody z różnymi parametrami w interfejsie PHP?

Pomysł jest o interfejs:

interface Loggable 
{ 
    public function log() ; 
} 

i 2 klasy implementujące ten interfejs:

class Syslogger implements Loggable 
{ 
    public function log() 
    { 
     ... 
    } 
} 

class QMSLogger implements Loggable 
{ 
    public function log($queueName) 
    { 
     ... 
    } 
} 

Jedynym sposobem mogę przyjść ze jest o tablicę jako parametr i używać go na jednej klasie, a nie na drugiej ... ale to trochę śmierdzi: P

+5

Jeśli metoda akceptuje parametr w jednym przypadku, a nie w innym, to nie jest to ten sam interfejs! – deceze

+0

Tak Przypuszczam, że jest to bardziej poprawny sposób, ale chciałem być w stanie wstrzyknąć obie klasy, aby móc zmienić system rejestrowania ... Myślę, że byłem w błędzie – Khriz

+2

Cóż, to jest rzeczywiście możliwe w przypadku '$ queueName' domyślnie NULL ('public function log ($ queueName = null) {...}'), ale zgadzam się z deceze tutaj. –

Odpowiedz

8

Jak stwierdzono w komentarzach, to nie jest ten sam interfejs. Jeśli nie można uogólniać interfejsu we wszystkich możliwych implementacji rejestratora, należy różnic konfiguracyjnych część konstruktora przykład:

class QMSLogger implements Loggable { 

    protected $queueName; 

    public function __construct($queueName) { 
     $this->queueName = $queueName; 
    } 

    public function log() { 
     ... 
    } 

} 
8

Pytasz, czy jest to możliwe: Tak to jest, ale ...

przypadku zastosowania interfejs, musisz musi przestrzegać jego umowy.

interface Loggable 
{ 
    public function log(); 
} 

kontrakt ten interfejs jest można nazwać log() bez parametru.

W celu zachowania, które można zrobić parametr opcjonalny:

class QMSLogger implements Loggable 
{ 
    public function log($queueName = null) 
    { 
     ... 
    } 
} 

To perfectly valid PHP i szanuje zasada podstawienia liskov. Oczywiście, nie wolno używać tego parametru opcjonalnego podczas kodowania z interfejsem, w przeciwnym razie oczywiste jest przerwanie interfejsu. Taki parametr może być przydatny tylko wtedy, gdy używasz implementacji (np. W części kodu, która jest ściśle powiązana z QMSLogger).

Prawdopodobnie nie jest to rozwiązanie problemu, ponieważ $queueName wydaje się być wartością konfiguracyjną i może być lepiej przekazać ją w konstruktorze klasy (jak wyjaśniono w drugiej odpowiedzi).

1

Można również przekazać parametry w postaci tablicy, w ten sposób respektować umowę z jednej strony, a także być elastyczne, aby wstawić dowolne wartości z dowolnej ilości wewnątrz tablicy, to sprawdzić:

abstract class FeaturesAbstract 
{ 
    /** 
    * @param array $paramsArray 
    * 
    * @return mixed 
    */ 
    abstract public function addExecute($paramsArray); 
} 

i faktycznie korzysta z tej metody można wysłać parametry tak:

$this->abstract->addExecute(array('paramA' => $paramA, 'paramB' => $paramB)); 

a następnie wewnątrz konkretnej implementacji można uzyskać parametry takie jak ten:

/** 
    * @param array $paramsArray 
    * 
    * @return void 
    */ 
    public function addExecute($paramsArray) { 

    $a = $paramsArray['paramA']; 
    $b = $paramsArray['paramB']; 
    $c = ... 
} 

Powodzenia :)

Powiązane problemy