Jakie są zalety „kombinowanego” narzędzia Getter / Setter kontra poszczególne metody?

12

Tak nazywam „łączoną” metodę pobierającą / ustawiającą (z jQuery):

var foo = $("<div>This is my HTML</div>"),
    myText;

myText = foo.text(); // myHTML now equals "This is my HTML" (Getter)
foo.text("This is a new value"); // The text now equals "This is a new value")

Jest to ta sama logika z osobnymi (teoretycznymi) metodami:

var foo = $("<div>This is my HTML</div>"),
    myText;

myText = foo.getText(); // myHTML now equals "This is my HTML" (Getter)
foo.setText("This is a new value"); // The text now equals "This is a new value")

Moje pytanie:

Dlaczego projektując bibliotekę taką jak jQuery, wybrałbyś pierwszą trasę, a nie drugą? Czy drugie podejście nie jest jaśniejsze i łatwiejsze do zrozumienia na pierwszy rzut oka?

Levi Hackwith
źródło
6
Martin Fowler nie jest fanem tego, co nazywa „przeciążonymi ustawiaczami getterów
vaughandroid
1
Kiedyś lubiłem metodę dzielenia get / set (myślę, że dzięki temu kod stał się bardziej „oczywisty”), ale obecnie uważam, że przeciążony wzorzec getter / setter jest bardziej atrakcyjny. Może sprawić, że kod będzie czystszy. Nigdy nie lubiłem kompromisu pana Fowlera. Wydaje mi się, że to najgorszy z obu światów.
Brian Knoblauch,
Jedynym prawdziwym argumentem Martina Fowlera jest to, że „getter” przekazuje argument, w którym to przypadku jest on mylący dla czytelnika, ponieważ nie wygląda jak getter. Do tej pory doszedłem do wniosku, że jeśli trzymasz się konwencji, że getter nie przyjmuje żadnych argumentów, a setter bierze jeden, to, wraz z jasnymi komentarzami API, podejście jQuery / Angular powinno być w porządku. Na razie.
zumalifeguard

Odpowiedzi:

13

Czysto spekulując tutaj, ale byłbym skłonny wierzyć, że programiści jQuery, którzy zastosowali wiele funkcjonalnych stylów w strukturze jQuery, wyraźnie skłaniają się ku paradygmatowi funkcjonalnemu.

Biorąc pod uwagę, że w paradygmacie funkcjonalnym istnieje silna kultura ograniczania redundancji i można argumentować, że drugie podejście ma niepotrzebną redundancję. Pierwsze podejście może nie być jasne dla kogoś, kto jest przyzwyczajony do wszystkich popularnych języków imperatywnych, ale bezsprzecznie robi więcej przy mniejszej liczbie, stosując tylko jedną metodę zamiast dwóch. Może to być niebezpieczne, ale jest to powszechne narzędzie w paradygmacie funkcjonalnym i coś, do czego szybko się przyzwyczajamy.

Poćwicz w paradygmacie funkcjonalnym, a szybko pokonasz to pragnienie ceremonii i nauczysz się doceniać umiejętność robienia więcej za mniej. Chociaż jest to wyraźnie subiektywny wybór oparty na preferencjach w taki sam sposób, w jaki wiele osób ma preferencje dotyczące zarządzania białymi odstępami. W ten sposób nie twierdzę, że jeden sposób jest lepszy, a raczej to, że ludzie są do tego przyzwyczajeni. Prawdopodobnie dlatego jQuery ma takie podejście.

Właśnie dlatego uważam, że twórcy jQuery to zrobili i ogólnie rzecz biorąc, dlaczego ktoś może przyjąć takie podejście.

Jimmy Hoffa
źródło
2
Zgadzam się, a do tego dodam chęć jak największego zmniejszenia rozmiaru JS.
Mt S
-1 dla punktów imperatywnych / szczegółowych i funkcjonalnych / niejawnych.
3
@MattFenwick Nie chcę obrażać, czy mówisz, że to nieprawda, że ​​funkcjonalny paradygmat skłania się ku niejawności, podczas gdy imperatywny paradygmat skłania się ku jawności? Nie twierdzę, że jedno z nich jest lepsze, po prostu można się przyzwyczaić do jednego lub drugiego, co spowodowałoby, że automatycznie robiłbyś rzeczy w ten sposób, w przeciwieństwie do innych (to samo dotyczy obu)
Jimmy Hoffa
@ Jimmy nie ma problemu; Chodziło mi o to, że z mojego doświadczenia wynika, że ​​niejawność / jawność jest ortogonalna względem FP / imperatywu.
@MattFenwick może być, ale powiedziałbym, że oprócz wnioskowania o typie, który pozwala na wiele niejawności i jest wspólny dla systemu typów HM, inne rzeczy wspólne dla języków FP skłaniają się ku niejawności, podobnie jak wszystkie operatory jako funkcje, w których funkcja nie ma wyraźnej nazwy, tylko symbol, którego należy się uczyć i znać w sposób dorozumiany, lub powszechne stosowanie list lub krotek wymagających niejawnej wiedzy o znaczeniu i lokalizacji członka zamiast DU (pomyśl o tym, jak działa monada pisarza). Mam też tendencję do dostrzegania podobieństwa nazw parametrów jednoliterowych, ale możesz mieć rację
Jimmy Hoffa
2

Formularz

foo.text("This is a new value"); 

może sugerować wiele rzeczy. Najczęściej sugeruje fooobiekt, który za pomocą metody o nazwie textprzyjmowanie ciągu, który coś robi . Nic nie wskazuje na to, że jest to w ogóle własność.

W wielu językach można to uznać za skróconą formę

var result = foo.text("This is a new value"); 

gdzie wynik jest odrzucany. Podejście to jest więc zbyt dwuznaczne, aby być skutecznym sposobem na ustawienie właściwości (z punktu widzenia czytelności kodu).

Robert Harvey
źródło
To doskonały punkt! Włożyłem gogle FP podczas czytania javascript i rzeczy wyglądają inaczej, więc nawet o tym nie myślałem, ale gdybym zobaczył taki kod w C #, miałbym dokładnie taką reakcję, o której mówisz „Wth robi ta metoda ?? ”.
Jimmy Hoffa
1

To trochę spekulacyjne, ale oto mój strzał.

jQuery w pełni obejmuje funkcjonalną naturę javascript. To sprawia, że ​​jest tak niesamowity, ale może sprawić, że wielu programistów podrapie się po głowie, gdy pochodzą z czysto językowego języka OO, takiego jak Java. Wydaje się, że łamie wszelkie konwencje i dobre praktyki.

Język funkcjonalny kładzie nacisk na deklaratywną składnię. Mają tendencję do czytania jak stwierdzenie faktu, a nie jak polecenia. Przykład

var eligible = customers.where(c => c.age > 30);

które można odczytać jako „uprawnionymi klientami są klienci w wieku powyżej 30 lat”. Natomiast język imperatywny brzmi jak sekwencja poleceń

for (customer in customers)
    if (customer.age > 30)
        eligible.add(customer)

Można to odczytać jako „Sprawdź każdego klienta, a jeśli jego wiek przekracza 30 lat, dodaj go do odpowiedniej kolekcji”

Dodanie aa seti getoperacji sprawiłoby, że jQuery czułoby się jak biblioteka imperatywna. Możesz ograniczyć sposób czytania poniższych instrukcji

// The element tag have an html of <p>hello</p>
$("#element").html("<p>hello</p>"); 

// content represent the html of the element tag
var content = $("#element").html();


//Imperative style

// Set the element tag to an inner html of <p>hello</p>
$("#element").setHtml("<p>hello</p>");

//Get the html of #element, and put it in the content variable
var content = $("#element").getHtml();

Utrzymując czasownik działań poza interfejsem jQuery, sprawili, że poczuł się jak deklaratywny interfejs API. Nadaje bibliotece spójny, funkcjonalny charakter. Dlatego myślę, że przeciążyli słowa kluczowe.

Laurent Bourgault-Roy
źródło
1

To sprawia, że ​​zachowuje się trochę bardziej jak właściwości , które dopiero niedawno zostały wprowadzone do JavaScript, a zatem nie są jeszcze powszechnie używane, szczególnie w bibliotekach takich jak jQuery, które mają pomóc w usunięciu niezgodności przeglądarki.

Jeśli kiedykolwiek spojrzałeś na definicję klasy pełną takich właściwości, przedrostki „set” i „get” wyglądają na zbędne, ponieważ dodanie parametru value już mówi, że jest to ustawiacz. Martin Fowler ma rację, jeśli chodzi o metody pobierające, które wymagają parametru, ale nawet w tym kontekście parametr dodatkowej wartości wyraźnie oznacza settera, a także fakt, że setter rzadko pojawia się po prawej stronie zadania. A kiedy piszesz kod, i tak musisz przejrzeć dokumentację biblioteki.

Ponieważ prosiłeś tylko o zalety, nie będę omawiał wad.

Karl Bielefeldt
źródło