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

Powoduje, że metody modyfikujące zwracają obiekt hosta, dzięki czemu można wywoływać wiele modyfikatorów w jednym wyrażeniu .

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.



Modified text is an extract of the original Stack Overflow Documentation
Licencjonowany na podstawie CC BY-SA 3.0
Nie związany z Stack Overflow