Łączenie pobierających i ustawiających

16

Biblioteki JavaScript, takie jak jQuery, łączą „getters” i „setters” w interfejsie programowania, na przykład:

 $('element').css({'color','blue'});

ustawi kolor lub

 $('element').css();

dostanie css dla elementu.

Czy istnieje nazwa takiego wzorca i czy dobrą praktyką jest stosowanie go w aplikacjach?

Yannis
źródło

Odpowiedzi:

12

Martin Fowler nazwał go niedawno W tym artykule przeciążono narzędzie pobierające i ustawiające :

Ostatnio przeszukiwałem Javascript, a jedną rzeczą, która mnie uderzyła, jest nawyk używania tej samej nazwy funkcji dla gettera i setera. Więc jeśli chcesz sprawdzić wysokość swojego banera w jQuery, którego byś użył, $("#banner").height()a jeśli chcesz zmienić wysokość, której byś użył $("#banner").height(100).

Konwencja ta jest mi znana, ponieważ była używana przez Smalltalk. Możesz uzyskać wartość za pomocą banner heighti zmienić ją za pomocą banner height: 100. Świadomość, że była to konwencja smalltalk, wystarcza, by oczekiwać, że mi się spodoba, ponieważ mam daleką, ale stałą miłość do tego języka. Ale nawet najlepsze rzeczy mają wady i nie mogę ukryć mojej niechęci do tego stylu kodowania ...

Pomimo tych preferencji, musisz przestrzegać konwencji języka, z którym masz do czynienia. Gdybym ponownie pisał Smalltalk, nadal używałbym, height:100aby zachować spójność z konwencjami języka. JavaScript nie jest jednak znany z tego, że ma silne konwencje, więc tutaj wolałbym unikać tej konwencji, nawet jeśli jest używana przez jQuery ...

louisgab
źródło
1
Chociaż zazwyczaj zgadzam się z większością tego, co mówi Fowler, nie zgadzam się z jego niechęcią do tego. Jego rozumowanie jest takie, że JavaScript nie ma silnych konwencji, takich jak Smalltalk, co czyni go użytecznym tam. Jednak jQuery ma silne konwencje, a JavaScript nie jest jQuery. jQuery to framework.
CaffGeek,
@Chad, muszę się z tym nie zgodzić. Jego argumentem jest to, że brakuje mu jednoznaczności i spójności. Mówi, że używa go w Smalltalk, ponieważ spójność z innymi przebija jego obawy. Nie twierdzi, że konwencje Smalltalk w jakiś sposób łagodzą lub eliminują problem.
Winston Ewert
2

Nazywa się to „przeciążanie metod” w językach OO lub „przeciążanie funkcji” w językach innych niż OO.

To, czy jest to dobra praktyka, jest tematem niemal tyle samo debaty, co osoby pobierające / ustawiające kontra członkowie publiczni. Osoby po stronie profesjonalistów i przeciwników prawdopodobnie obcinają zęby w językach, które miały tę funkcję lub jej nie posiadały i są ustawione na swój sposób. Używam go i lubię praktykę z wielu powodów:

  • Kontekst, w którym jest używany, całkiem dobrze oddziela jeden od drugiego.
  • Dodanie getlub setdo nazwy metody dodaje gadatliwość.
  • Jeśli istnieje wiele pobierających (np. Jeden dla inti jeden dla double), zmiana typu w LHS zadania ( int x = foo.bar()vs. double x = foo.bar()) nie wymaga zmiany kodu ( barAsInteger()vs. barAsDouble()) na prawą stronę, jeśli klasa zapewnia oba. Wadą tego jest to, że czasami może być trudno dokładnie określić, która metoda jest wywoływana, po prostu patrząc na kod.
Blrfl
źródło
W C ++ nazywa się to także „przeciążeniem funkcji”.
DeadMG,
Oba terminy mają zastosowanie do C ++, ponieważ ma on zarówno metody, jak i nagie funkcje.
Blrfl,
1

Ponieważ JavaScript nie ma rzeczywistych właściwości (gdzie ustawienie wartości może faktycznie wykonać kod), wzór jest tym, który implementuje idiom właściwości. (Nawet jeśli nazwiesz to czymś innym.)

W językach implementujących nieruchomości zrobiłbyś to zamiast tego:

element.css = ...
x = element.css

Jeśli użyjesz wzorca JavaScript w języku, który obsługuje właściwości, zrobiłbyś coś nienormalnego. To prawdopodobnie nie byłby dobry pomysł. Obsługuj właściwości tak, jak język ma je obsługiwać, aby nie mylić innych osób pracujących z tobą.

John Fisher
źródło
„gdzie ustawienie wartości może faktycznie wykonać kod”. To już nie jest prawda. Jest to częścią specyfikacji od ECMA 5
Demian Brecht
@Demian: Ale JQuery działa w przeglądarkach, które nie implementują ECMA 5.
John Fisher
Nie wspominałem nic o kompatybilności z różnymi przeglądarkami, tylko że cytat jest niepoprawny jak napisano.
Demian Brecht
@Demian: Tekst „JavaScript nie ma faktycznych właściwości” jest poprawny, jeśli założymy, że używa on najczęściej dostępnych wersji JavaScript. Ponieważ dyskutujemy w kontekście implementacji JQuery, stwierdzenie byłoby poprawne. Dziękujemy za zwrócenie uwagi, że nowsze wersje JavaScript mają prawdziwe właściwości.
John Fisher
1

Jestem całkowicie przeciwny temu z prostego powodu: Klasa, Metoda lub Funkcja powinny po prostu zrobić jedną rzecz - moim zdaniem, połączenie metody getteri setterspowoduje naruszenie tej zasady. Jako wynik:

  1. returnWartość funkcji zmienia się w zależności czy getter lub setter blok zostanie wykonany. Ten może po prostu doprowadzić cię do koszmaru utrzymania. Twoja metoda powinna w każdym przypadku zwrócić tylko jeden typ danych / obiektu - lub zwrócić null, falselub zgłosić exceptionbłąd.
  2. Pisanie testów jednostkowych będzie trudniejsze, ponieważ funkcja ta odpowiada za dwie zupełnie różne funkcje.
  3. Pisanie dokumentacji dla takiej metody lub funkcji jest trudniejsze z oczywistych powodów.
  4. Nie będzie to spójne, gdy potrzebne będą różne metody pobierania - jak już wspomniano w Blrflodpowiedzi.
Mahdi
źródło
0

Myślę, że szukasz properties

thekip
źródło
To nazwa funkcji udostępnianej w języku C # (i być może w innych językach .NET?), Która jest podobna do tej, ale tak naprawdę nie jest to ta sama rzecz.
Thomas Owens
Wikipedia zgadza się jednak: en.wikipedia.org/wiki/Property_(programming)
thekip
Dzięki, naprawdę nie możesz mieć przypadek powiedzieć, gdzie ustawić lub otrzymać wynagrodzenie osób w aplikacji person.salary('10000')lub person.salary()lub podobny.
yannis,
1
Nie rozumiem jak. „Właściwości są odczytywane i zapisywane jak pola”, co nie jest prawdziwe w przykładzie w oryginalnym poście. Tam wykonywane są jawne wywołania metod. Jest bardzo podobny, ale nie dokładnie taki sam.
Thomas Owens
1
@yannis To nie jest poprawne. JavaScript ma składnię właściwości i wcale nie jest to, co opisałeś w pierwotnym pytaniu. Zobacz en.wikipedia.org/wiki/Property_(programming)#JavaScript, aby dowiedzieć się, jak zaimplementować i używać właściwości w JavaScript.
Thomas Owens