2013-04-17 8 views
15

W firmie, w której pracuję, jest dokument opisujący dobre praktyki, których powinniśmy przestrzegać w Javie. Jednym z nich jest, aby unikać metod, które zwracają this, jak na przykład w:Co jest złego w zwrocie?

class Properties { 

    public Properties add(String k, String v) { 
    //store (k,v) somewhere 
    return this; 
    } 

} 

chciałbym mieć taką klasę tak, że jestem w stanie napisać:

properties.add("name", "john").add("role","swd"). ... 

Widziałem takie idiom wiele razy, jak w StringBuilder i nie znajduj w tym nic złego.

Ich argumentacja jest:

... może być źródłem problemów z synchronizacją lub nieudanych oczekiwań dotyczących stanów obiektów docelowych.

Nie mogę wymyślić sytuacji, w której może to być prawda, czy którykolwiek z was może dać mi przykład?

EDIT Dokument nie precyzuje nic o zmienności, więc nie widzę diference pomiędzy łańcuchowym połączeń i idzie:

properties.add("name", "john"); 
properties.add("role", "swd"); 

Postaram się skontaktować z pomysłodawców , ale chciałem to zrobić z załadowanymi pistoletami, dlatego napisałem to pytanie.

SOLVED: Muszę porozmawiać z jednym z autorów, jego pierwotnym zamiarem było najwyraźniej w celu uniknięcia uwalniania przedmiotów, które nie są jeszcze gotowe, jak we wzorcu Builder, i wyjaśnił, że jeśli przełącznik kontekst dzieje się między połączeniami, obiekt może być w nieprawidłowym stanie. Przekonywałem, że nie miało to nic wspólnego z powrotem do systemu, ponieważ mógłbyś popełnić ten sam błąd, wywołując metody jeden po drugim i miał więcej do czynienia z prawidłową synchronizacją procesu budowania. Przyznał, że dokument może być bardziej wyraźny i wkrótce to zmieni. Zwycięstwo jest moje/nasze!

+6

"Problemy synchronizacji"? Nie mogę sobie wyobrazić, jak to by z tego powstało (kalambur nie jest zamierzony, ale tolerowany). Podobnie jak prawie wszystkie inne wzorce ma dobre zastosowania i niewłaściwe wykorzystanie, ale nie rozumiem tego, jakie masz uzasadnienie. Może poproś autorów tego dokumentu o wyjaśnienia. –

+0

Istnieje inny post o tym na http://stackoverflow.com/questions/1345001/is-it-bad-practice-to-make-a-setter-return-this – Walid

+0

Nie rozumiem tej argumentacji. –

Odpowiedz

5

Jedyna poważna podstawa dla praktyki jest unikanie zmienny obiektów; krytyka, że ​​jest "myląca" i prowadzi do "nieudanych oczekiwań", jest dość słaba.Nie należy nigdy używać obiektu bez uprzedniego zapoznania się z jego semantyką, a wymuszanie ograniczeń w interfejsie API tylko po to, aby zadowolić tych, którzy zrezygnowali z czytania Javadoc, nie jest dobrą praktyką w ogóle. —, zwłaszcza, że, jak zauważono, wracają this Osiągnięcie płynnego projektowania interfejsu API jest jednym ze standardowych podejść w języku Java, a nawet bardzo pożądanym.

6

Zgaduję, że są one przeciwko zmiennemu stanowi (i często są słusznie). Jeśli nie projektujesz płynnych interfejsów zwracających this, a zamiast tego zwracasz nową niezmienną instancję obiektu ze zmienionym stanem, możesz uniknąć problemów z synchronizacją lub nie mieć "failed expectations about the states of target objects". To może wyjaśniać ich wymagania.

+4

Prawdopodobnie ten punkt powinien być wyraźnie wymieniony. – derabbink

+0

Czy mógłbyś wyjaśnić, w jaki sposób powrót z metody instancji wpływa na niezmienność? Co jest złego w powrocie do referencji do niezmiennego obiektu? – Mikhail

1

Myślę, że czasami takie podejście może być bardzo przydatne, na przykład w schemacie "konstruktora".

Mogę powiedzieć, że w mojej organizacji tego rodzaju rzeczy są kontrolowane przez zasady sonaru i nie mamy takiej zasady.

Innym domysłem jest, że być może projekt został zbudowany na istniejącej bazie kodu i jest to rodzaj restrykcji ze starszego okresu.

Więc jedyne co mogę zasugerować tutaj jest rozmawiać z ludźmi, którzy pisali ten dokument :)

Hope this helps

0

Sądzę, że w niektórych sytuacjach użycie tego wzoru jest całkowicie dopuszczalne.

Na przykład, jako programista Swing, używam GridBagLayout dość często ze względu na jego zalety i elastyczność, ale każdy, kto kiedykolwiek go używał (z jego stronnikiem w kryminalizacji GridBagConstraints) wie, że może on być dość szczegółowy i niezbyt czytelny.

Typowym obejściem, które widziałem w Internecie (i tym, którego używam) jest podklasa GridBagConstraints (GBConstraints), która ma ustawnik dla każdej właściwości, a każdy program ustawiający zwraca tę wartość. Umożliwia to deweloperowi powiązanie różnych właściwości w zależności od potrzeb.

Wynikowy kod ma około 1/4 rozmiaru i jest o wiele bardziej czytelny/łatwy w utrzymaniu, nawet dla zwykłego programisty, który może nie być obeznany z korzystaniem z GridBagConstaints.

Powiązane problemy