PHP
Wzorce projektowe
Szukaj…
Wprowadzenie
Ten temat zawiera przykłady dobrze znanych wzorców projektowych zaimplementowanych w PHP.
Łączenie metod w PHP
Metoda tworzenia łańcuchów jest techniką wyjaśnioną w książce Martina Fowlera Języki specyficzne dla domeny . Łańcuch metod jest podsumowany jako
Zastanów się nad tym niekodującym / regularnym fragmentem kodu (przeniesionym do PHP z wyżej wymienionej książki)
$hardDrive = new HardDrive;
$hardDrive->setCapacity(150);
$hardDrive->external();
$hardDrive->setSpeed(7200);
Łączenie metod pozwoliłoby ci napisać powyższe instrukcje w bardziej zwarty sposób:
$hardDrive = (new HardDrive)
->setCapacity(150)
->external()
->setSpeed(7200);
Wszystko, co musisz zrobić, aby to zadziałało, to return $this
w metodach, z których chcesz połączyć:
class HardDrive {
protected $isExternal = false;
protected $capacity = 0;
protected $speed = 0;
public function external($isExternal = true) {
$this->isExternal = $isExternal;
return $this; // returns the current class instance to allow method chaining
}
public function setCapacity($capacity) {
$this->capacity = $capacity;
return $this; // returns the current class instance to allow method chaining
}
public function setSpeed($speed) {
$this->speed = $speed;
return $this; // returns the current class instance to allow method chaining
}
}
Kiedy z niego korzystać
Podstawowymi przypadkami użycia łańcucha metod jest budowanie wewnętrznych języków specyficznych dla domeny. Metoda tworzenia łańcuchów jest elementem składowym konstruktorów wyrażeń i płynnych interfejsów . Jednak nie jest to równoznaczne z tymi . Łączenie metod tylko je umożliwia. Cytując Fowlera:
Zauważyłem również powszechne nieporozumienie - wiele osób zdaje się utożsamiać płynne interfejsy z łańcuchem metod. Z pewnością łańcuchowanie jest powszechną techniką stosowaną w przypadku płynnych interfejsów, ale prawdziwa płynność to znacznie więcej.
Mając to na uwadze, stosowanie metody łączenia łańcuchów w celu uniknięcia pisania obiektu hosta jest przez wielu uważane za zapach kodu . Powoduje to, że interfejsy API są nieoczywiste, szczególnie w przypadku mieszania z interfejsami API bez łączenia łańcuchów.
Dodatkowe uwagi
Rozdzielanie zapytań poleceń
Rozdzielanie zapytań dowodowych to zasada projektowania opracowana przez Bertranda Meyera . Stwierdza, że metody mutujące stan ( polecenia ) nie powinny niczego zwracać, podczas gdy metody zwracające coś ( zapytania ) nie powinny mutować stanu. Ułatwia to rozumowanie systemu. Łączenie metod narusza tę zasadę, ponieważ mutujemy stan i coś zwracamy.
Getters
Korzystając z klas, które implementują łączenie metod, zwróć szczególną uwagę podczas wywoływania metod pobierających (czyli metod, które zwracają coś innego niż $this
). Od pozyskiwaniu musi zwrócić wartość inną niż $this
, łańcuchowym dodatkową metodę na getter sprawia, że działają na wezwanie dostał wartości, a nie od oryginalnego obiektu. Chociaż istnieją pewne przypadki użycia łańcuchowych modułów pobierających, mogą one powodować, że kod będzie mniej czytelny.
Prawo Demetera i wpływ na testy
Łańcuch metod przedstawiony powyżej nie narusza prawa Demetera . Nie ma to również wpływu na testowanie. Jest tak, ponieważ zwracamy instancję hosta, a nie jakiegoś współpracownika. Jest to powszechne nieporozumienie wynikające z mylenia zwykłego łączenia łańcuchów metod z płynnymi interfejsami i konstruktorami wyrażeń . Tylko wtedy, gdy metoda łączenia zwróci inne obiekty niż obiekt hosta , naruszysz Prawo Demetera i zakończysz próbnymi festynami w testach.