Jak nazywa się ten idiom, używając metody łączenia łańcuchów do zbudowania obiektu?

21

Często używam wzorca, w którym używam łączenia łańcuchowego do ustawiania obiektu, podobnego do wzoru Builderlub Prototype, ale nie tworzę nowych obiektów przy każdym wywołaniu metody, zamiast tego modyfikując oryginalny obiekt.

Przykład:

new Menu().withItem("Eggs").withItem("Hash Browns").withStyle("Diner");

Zastanawiam się tylko, czy istnieje nazwa tego wzorca i czy jest on uważany za anty-wzorzec, ponieważ chociaż może czytać płynniej, może prowadzić do długich łańcuchów metod.

Garrett Hall
źródło
3
Płynny interfejs to kwestia stylu. Jeśli piszesz API, podaj alternatywne formularze.
Oded
1
Aby uzyskać więcej dyskusji, spójrz na to pytanie: programmers.stackexchange.com/questions/69519/...
Eric King
@Oded Możliwe jest użycie takiego interfejsu API bez tworzenia łańcucha, po prostu tworząc każde wywołanie osobną instrukcją, czy masz inny pomysł na alternatywę?
Garrett Hall
@GarrettHall - Oczywiście, że jest to możliwe, ale w końcu nazywasz rzeczy menu.withStyle("")bez kontekstu. W takim przypadku potrzebujesz dwóch interfejsów API.
Oded
2
@GarrettHall Punktem „płynnego interfejsu” jest łańcuch metod, który należy czytać jak zdanie. W tym sensie długi łańcuch metod nie jest uważany za zły. Ale i tutaj zgadzam się z Odedem, najlepiej byłoby również zapewnić tę samą funkcjonalność w bardziej konwencjonalnej składni. W ten sposób programista może wybrać metodę, której należy użyć.
Eric King,

Odpowiedzi:

37

Płynny interfejs

Zawsze słyszałem o tej metodzie nazywanej „ płynnym interfejsem ”, jak wymyślili ją Eric Evans ( sława Domain Driven Design ) i Martin Fowler ( sława Agile Manifesto ).

Główne wady to czytelność (którą niektórzy uwielbiają, a niektórzy nienawidzą) oraz fakt, że w niektórych przypadkach może być trudniej debugować, ponieważ cały łańcuch działań może być uważany za jedno stwierdzenie podczas jego przechodzenia.

Z pewnością nie uważam tego za anty-wzór, chociaż sam użyłem tej techniki tylko kilka razy.

Eric King
źródło
4
Zwróć uwagę, że zwolennicy bardzo nalegają, aby płynny interfejs wymagał znacznie więcej niż tylko łączenia łańcuchowego metod, chociaż często nie jest jasne, co jeszcze rozumie się pod tym pojęciem.
Kilian Foth,
Czy to jest wspólne, że cały łańcuch jest uważany za jedno stwierdzenie? To brzmi jak źle zaprojektowany problem z debuggerem.
blueberryfields
Nie natknąłem się na debugger, który traktuje łańcuchy jako pojedyncze stwierdzenie, ale nadal może być to bolesne, jeśli interesuje Cię tylko jedna z metod pod koniec łańcucha, w jednym określonym łańcuchu.
vaughandroid
1
Pracuję w języku C #, a debuger .NET pozwala mi dobrze przejść do poszczególnych metod. Inne języki, nie jestem tego taki pewien.
Eric King,
1
@KilianFoth Jak zauważono w komentarzach do pytania, powiązane metody w płynnym interfejsie powinny być czytelne prawie jak zdanie. Czasami oznacza to, że poszczególne metody powinny mieć inne nazwy niż jest to uważane za dobrą praktykę
Izkata
5

Takie łączenie łańcuchów jest zwykle nazywane płynnym interfejsem, gdy występuje pewien przepływ lub możliwość wykrycia w łańcuchu. Alternatywnie możesz pomyśleć o interfejsie API, takim jak jQuery, który opiera się w dużej mierze na tworzeniu łańcuchów metod, jako nie „płynnym”, ponieważ nie kładzie się takiego samego nacisku na wykrywalność - jest to bardziej wygodne.

Na przykład (używając withx, withy) możesz rozważyć ten wariant wzorca Buildera, ponieważ masz wyspecjalizowaną klasę, która, biorąc pod uwagę niektóre stany (wywołania metod), wie, jak zwrócić poprawnie skonfigurowany obiekt.

To nie jest anty-wzór, jeśli jest właściwie stosowany.

pfries
źródło
Co to jest odkrywczość? Możliwość znalezienia potrzebnych metod poprzez autouzupełnianie interfejsu API?
Josiah Yoder
Nie znam jQuery. W jaki sposób ich łańcuchy metod służą jedynie wygodzie, a nie wykrywalności? Ponieważ istnieje tak wiele sposobów na połączenie, to jest przytłaczające nawet przy autouzupełnianiu?
Josiah Yoder
3

czy jest to uważane za anty-wzór,

zdecydowanie nie jest to anty-wzór. jQuery jest prawdopodobnie najczęściej używaną implementacją tego.

ponieważ chociaż potrafi czytać płynniej, może prowadzić do długich łańcuchów metod

Tak, może, ale jaka jest alternatywa? Możesz skończyć z prawie prostym angielskim zdaniem, a API prowadzi cię do tego, co jest dostępne i odpowiednie.

Nim Chimpsky
źródło
... i dostajesz to, co chcesz w 1 linii, zamiast 8-10. Co jest dobre, jeśli piszesz tylko jeden linijka w terminalu. Łatwiej jest przywołać 1 polecenie niż 10. Ponieważ jest płynny, a metody mają opisowe nazwy, łatwiej jest go również odczytać. Niestety dużo tego nie można zrobić w Python2 w Python3 / Python4.
mckenzm,
-3

Nazywa się to wzorem „wraku pociągu”.

(To jest anty-wzorzec i jest przeciwko Clean Code)

Wzór „wraku pociągu” narusza Prawo Demetera .

Marc
źródło
3
Nie jest to to samo, co metoda tworzenia łańcucha w artykule, do którego prowadzi link, w którym znajduje się przykład a.getB().getC().doSomething(). Ten przykład jest zły, ponieważ „Twoja metoda może wywoływać metody bezpośrednio na własnych polach (ale nie na polach pól)”. Tutaj powstaje tylko 1 obiekt i „możesz się bawić zabawkami, które sam stworzyłeś”.
Nic