Ostatnio dużo studiowałem na temat funkcjonalności i sposobów korzystania z biblioteki Facebooka JavaScript React.js. Mówiąc o swoich różnic z resztą świata JavaScript często dwoma stylami programowania declarative
i imperative
są mentionned.
Jaka jest różnica między nimi?
Imperative programming: telling the "machine" how to do something, and as a result what you want to happen will happen. Declarative programming: telling the "machine"1 what you would like to happen, and let the computer figure out how to do it.
Odpowiedzi:
Styl deklaratywny, taki jak to, co ma react, pozwala kontrolować przepływ i stan w aplikacji poprzez powiedzenie „To powinno wyglądać tak”. Styl rozkazujący odwraca to i pozwala kontrolować aplikację, mówiąc „To jest to, co powinieneś zrobić”.
Zaletą deklaratywnego jest to, że nie grzęźniemy w szczegółach implementacji reprezentujących stan. Delegujesz komponent organizacyjny zapewniający spójność widoków aplikacji, więc musisz się tylko martwić o stan.
Wyobraź sobie, że masz lokaja, który jest swego rodzaju metaforą szkieletu. A chciałbyś zrobić obiad. W imperatywnym świecie powiedziałbyś im krok po kroku, jak zrobić obiad. Musisz podać te instrukcje:
Go to the kitchen Open fridge Remove chicken from fridge ... Bring food to the table
W deklaratywnym świecie po prostu opisałbyś, czego chcesz
I want dinner with chicken.
Jeśli twój kamerdyner nie wie, jak zrobić kurczaka, nie możesz działać w stylu deklaratywnym. Podobnie jak jeśli Backbone nie wie, jak zmutować się, aby wykonać określone zadanie, nie możesz po prostu powiedzieć mu, aby wykonał to zadanie. React może być deklaratywny, ponieważ na przykład „wie, jak zrobić kurczaka”. W porównaniu do Backbone, który tylko wie, jak komunikować się z kuchnią.
Umiejętność opisania stanu radykalnie zmniejsza powierzchnię dla błędów, co jest zaletą. Z drugiej strony możesz mieć mniejszą elastyczność w tym, jak rzeczy się dzieją, ponieważ delegujesz lub abstrahujesz od sposobu implementacji stanu.
źródło
Wyobraź sobie prosty składnik interfejsu użytkownika, taki jak przycisk „Lubię to”. Po dotknięciu zmienia kolor na niebieski, jeśli był wcześniej szary, i szary, jeśli był wcześniej niebieski.
Niezbędnym sposobem byłoby:
if( user.likes() ) { if( hasBlue() ) { removeBlue(); addGrey(); } else { removeGrey(); addBlue(); } }
Zasadniczo musisz sprawdzić, co aktualnie jest na ekranie i obsłużyć wszystkie zmiany niezbędne do przerysowania go z obecnym stanem, w tym cofnięcie zmian z poprzedniego stanu. Możesz sobie wyobrazić, jak skomplikowane może to być w prawdziwym scenariuszu.
Natomiast podejście deklaratywne byłoby następujące:
if( this.state.liked ) { return <blueLike />; } else { return <greyLike />; }
Ponieważ podejście deklaratywne oddziela obawy, ta część musi zajmować się tylko tym, jak interfejs użytkownika powinien wyglądać w określonym stanie, a zatem jest znacznie łatwiejsza do zrozumienia.
źródło
To świetna analogia:
* Konieczna odpowiedź : wyjdź z północnego wyjścia z parkingu i skręć w lewo. Jedź I-15 na południe, aż dojdziesz do zjazdu z autostrady Bangerter. Skręć w prawo przy wyjściu, jakbyś jechał do Ikei. Idź prosto i na pierwszych światłach skręć w prawo. Przejdź przez następne światła, a następnie skręć w lewo. Mój dom ma numer 298.
Deklaratywna odpowiedź : mój adres to 298 West Immutable Alley, Draper Utah 84020 *
https://tylermcginnis.com/imperative-vs-declarative-programming/
źródło
Aby pokazać różnice, najlepiej porównać React (deklaratywny) i JQuery (imperatyw).
W Reakcie wystarczy opisać końcowy stan interfejsu użytkownika w
render()
metodzie, nie martwiąc się o przejście z poprzedniego stanu interfejsu użytkownika do nowego stanu interfejsu użytkownika. Na przykład,render() { const { price, volume } = this.state; const totalPrice = price * volume; return ( <div> <Label value={price} className={price > 100 ? 'expensive' : 'cheap'} ... /> <Label value={volume} className={volume > 1000 ? 'high' : 'low'} ... /> <Label value={totalPrice} ... /> ... </div> ) }
Z drugiej strony, JQuery wymaga, abyś koniecznie zmienił stan interfejsu użytkownika, np. Wybierając elementy etykiety i aktualizując ich tekst i CSS:
updatePrice(price) { $("#price-label").val(price); $("#price-label").toggleClass('expansive', price > 100); $("#price-label").toggleClass('cheap', price < 100); // also remember to update UI depending on price updateTotalPrice(); ... } updateVolume(volume) { $("#volume-label").val(volume); $("#volume-label").toggleClass('high', volume > 1000); $("#volume-label").toggleClass('low', volume < 1000); // also remember to update UI depending on volume updateTotalPrice(); ... } updateTotalPrice() { const totalPrice = price * volume; $("#total-price-label").val(totalPrice); ... }
W prawdziwym scenariuszu będzie o wiele więcej elementów interfejsu użytkownika do zaktualizowania, a także ich atrybuty (np. Style CSS i nasłuchiwanie zdarzeń) itp. Jeśli zrobisz to bezwzględnie za pomocą JQuery, stanie się to skomplikowane i żmudne; łatwo zapomnieć o zaktualizowaniu niektórych części interfejsu użytkownika lub zapomnieć o usunięciu starych programów obsługi zdarzeń (powoduje to wyciek pamięci lub wielokrotne uruchamianie procedury obsługi) itd. To jest miejsce, w którym pojawiają się błędy, np. stan UI i stan modelu są poza synchronizacja.
Stany niezsynchronizowane nigdy nie zdarzają się w deklaratywnym podejściu Reacta, ponieważ musimy tylko zaktualizować stan modelu, a React jest odpowiedzialny za utrzymanie synchronizacji interfejsu użytkownika i stanu modelu.
Możesz również przeczytać moją odpowiedź na pytanie Jaka jest różnica między programowaniem deklaratywnym i imperatywnym? .
PS: z powyższego przykładu jQuery, możesz pomyśleć, co by było, gdybyśmy umieścili wszystkie manipulacje DOM w
updateAll()
metodzie i wywołali ją za każdym razem, gdy zmieni się którykolwiek z naszych stanów modelu, a interfejs użytkownika nigdy nie będzie zsynchronizowany. Masz rację i to właśnie robi React, jedyną różnicą jest to, że jQueryupdateAll()
spowoduje wiele niepotrzebnych manipulacji DOM, ale React zaktualizuje tylko zmienione elementy DOM, używając swojego algorytmu Virtual DOM Diffing .źródło
Kod imperatywny instruuje JavaScript, jak powinien wykonać każdy krok. Za pomocą kodu deklaratywnego mówimy JavaScriptowi, co chcemy zrobić, i pozwalamy JavaScriptowi wykonać kroki.
React jest deklaratywny, ponieważ piszemy kod, który chcemy, a React jest odpowiedzialny za pobranie naszego zadeklarowanego kodu i wykonanie wszystkich kroków JavaScript / DOM, aby doprowadzić nas do pożądanego wyniku.
źródło
Prawdziwym odpowiednikiem imperatywnego świata byłoby wejście do baru na piwo i przekazanie barmanowi następujących instrukcji:
- Weź szklankę z półki
- Postaw szklankę przed przeciągiem
- Opuścić uchwyt, aż szklanka będzie pełna
- Podaj mi szklankę.
Zamiast tego w świecie deklaratywnym powiedziałbyś po prostu: „Piwo, proszę”.
Deklaratywne podejście do proszenia o piwo zakłada, że barman wie, jak je podać, a to jest ważny aspekt działania programowania deklaratywnego.
W programowaniu deklaratywnym programiści opisują tylko, co chcą osiągnąć i nie ma potrzeby wymieniać wszystkich kroków, aby to zadziałało.
Fakt, że React oferuje podejście deklaratywne, czyni go łatwym w użyciu, a co za tym idzie, wynikowy kod jest prosty, co często prowadzi do mniejszej liczby błędów i większej łatwości utrzymania.
Ponieważ React stosuje deklaratywny paradygmat i nie ma potrzeby mówić mu, jak ma współdziałać z DOM; po prostu ZADEKLARUJESZ to, co chcesz zobaczyć na ekranie, a React wykona to za Ciebie.
źródło
Programowanie deklaratywne jest paradygmatem programowania… który wyraża logikę obliczenia bez opisywania jego przepływu sterowania.
Programowanie imperatywne to paradygmat programowania, który używa instrukcji zmieniających stan programu.
odnośnik: - https://codeburst.io/declarative-vs-imperative-programming-a8a7c93d9ad2
źródło
źródło
Zacznę od analogii: mam dwa samochody, w moich dwóch chcę, aby temperatura w moim samochodzie wynosiła normalną temperaturę pokojową ~ 72 ° F. W pierwszym (starszym) samochodzie mamy dwa pokrętła do regulacji temperatury (1 do regulacji temperatury i 1 do regulacji przepływu powietrza). Gdy zrobi się za gorąco, muszę przestawiać pierwsze pokrętło, żeby obniżyć temperaturę i może zmienić przepływ powietrza) i odwrotnie, jeśli jest za zimno. To niezbędna praca! Muszę sam zarządzać gałkami. W moim drugim (nowszym) aucie mogę ustawić / zadeklarować temperaturę. Co oznacza, że nie muszę bawić się pokrętłami, aby wyregulować temperaturę, którą mój samochód wie, że deklaruję / ustawiam ją na 72 ° F, a mój samochód wykona niezbędną pracę, aby uzyskać ten stan.
React działa tak samo, deklarujesz znacznik / szablon i statystyki, a następnie React wykonuje niezbędną pracę, aby utrzymać synchronizację DOM z twoją aplikacją.
<button onClick={activateTeleporter}>Activate Teleporter</button>
Zamiast
.addEventListener()
konfigurować obsługę zdarzeń, deklarujemy, czego chcemy. Po kliknięciu przycisku zostanie uruchomionaactivateTeleporter
funkcja.źródło
Deklaratywne a rozkazujące
Programowanie deklaratywne to jak proszenie przyjaciela o pomalowanie twojego domu. Nie obchodzi cię, jak to czyszczą, jakiego koloru używają do malowania, ile zasobów użyli do jego ukończenia.
//Declarative For Searching element from an array array.find(item)
Konieczne jest przeciwieństwo deklaratywnego. Typowym przykładem imperatywnego podejścia jest to, że powiedziałeś swojemu przyjacielowi, co ma zrobić, aby pomalować swój dom.
// Imperative Algo
def imperative_search(array, item) for i in array do if i == item return item end end return false end
źródło
To jest moje dotychczasowe zrozumienie:
Kod deklaratywny (prawie?) Zawsze jest warstwą abstrakcji nad kodem, która jest z natury bardziej imperatywna.
React pozwala na pisanie deklaratywnego kodu, czyli warstwy abstrakcji nad kodem imperatywnym, który bezpośrednio współdziała z DOM (np. Algorytm różnicujący ). Jeśli potrzebujesz napisać kod imperatywny (tj. Wchodzić w interakcję bezpośrednio z DOM), React zapewnia Refs jako lukę ucieczki .
źródło