Pożegnanie z Reduxem

A więc Redux, o ile był fajnym eksperymentem (naprawdę fajnie, że powstał) jest już zasłużony i musi odejść.

Pisałem już wcześniej o Reduxie, bardziej opisowo, w wyważony sposób:

http://13zmiennych.blogspot.com/2016/12/bedzie-cos-o-reduxie.html

teraz będzie natomiast wpis typowo nastawiony na krytykę.

A więc jedziemy. Co jest nie tak z Reduxem?


Programowanie w Redux jest niewygodne.

Ale wielu to nie przeszkadza, gdyż wśród fanów Reduxa jest silny syndrom sztokholmski. Ludzie, którzy żeby zrobić prostą rzecz muszą napisać ileś reducerów, dołożyć ileś middleware, ileś dodatkowych pomoczniczych bibliotek do Reduxa robionych przez community. Ale na koniec dnia będą się cieszyć, że w ogóle mieli okazję popisać w Reduxie pisząc w 100 linijek kodu to co by mogli napisać w 5 bez Reduxa. Czyli taka sztuka dla sztuki.

O ile we wcześniejszych swoich wpisach porównywałem WebStorma do demokracji, to Redux jest jak socjalizm (parafrazując znany cytat można stwierdzić, że "Redux jest to framework, w którym bohatersko pokonuje się trudności nieznane w żadnym innym frameworku").

Po części jest to wina języka (JavaScript słabo wspiera niemutowalne struktury, na których opiera swoje istnienie Redux), ale cóż, taki mamy język. Redux stara się z nim walczyć, ja wolę zaakceptować.


Redux nie rozwiązuje wcale problemów, które miał rozwiązywać.

Miało dać się łatwiej zapanować nad stanem w aplikacji, a mam wrażenie, że Redux wszystko jeszcze bardziej tylko utrudnia. Zmiany stanu są rozsiane po iluś reducerach (zwykle w innych plikach), do tego dochodzi do tego wszelaka magia, którą zwyczajowo się dodaje jak action creatory, różnego rodzaju middleware itp. To wszystko zaciemnia(!!!) zmiany stanu, i zaciemnia cały flow aplikacji. Pisanie w Redux to taki funkcyjny ravioli code

Ravioli code is a pejorative phrase for source code with lots of tiny, tightly-coupled objects. The tangled but explicit control structure of Spaghetti code is replaced with equally tangled but now implicit control flow using polymorphism. Overzealous separation and encapsulation of code can bloat call stacks and make navigation through the code for maintenance purposes more difficult.[16]

zamieńcie obiekty na "funkcje" w pierwszym zdaniu, to będzie mieć dobry obraz (tak, tak, polimorfizm też tu pasuje, ponieważ reducery są polimorficzne, zachowują się różnie w zależności od tego jaką akcję dostaną na wejściu).


Zbyt wiele abstrakcji, zbyt mało konkretów

Albo jak kto woli - w Redux jest zbyt dużo infrastruktury, a za mało logiki biznesowej.

Pisząc w Redux będziesz się zajmować pisaniem reducerów, kreatorów akcji, middleware, poznasz redux thunk, redux saga, poznasz koncepcję selektorów, High Level Componentów, teorię o smart i dumb componentach itp. itd.

Wszystko fajnie, wszystko bardzo cool wygląda.

Tylko, że to... nie ma wartości biznesowej. Te wszystkie cudne programistyczne artefakty i tak są tylko przykrywką, bo ważniejsze jest mięcho. Czyli to, co tak naprawdę te wszystkie piękne reducery robią od strony biznesowej (np. "są odpowiedzialne za logikę panelu administracyjnego użytkownika na portalu społecznościowym". Albo "pozwalają edytować posty na blogu"). I to ma wartość (a nie to, że sobie połączyłeś 50 reducerów w całość i stworzyłeś 10 abstrakcji).

I ludzie odrzuciwszy sprawdzony model MVC wchodzą w jakieś Reduxy i zamiast porządnej obiektówki, to tworzą rozmaite artefakty, które mają na celu zasymulować OOP w paradygmacie funkcyjnym (najśmieszniejsze są stałe dla akcji czy switch/case wszędzie - to takie OOP dla ubogich, gdzie akcje udają metody, a switch/case udają instancje obiektów).


Ogólna ubogość

prawie nic nie ma out of the box, a podstawową funkcjonalność Reduxa można odtworzyć w kilka linijek kodu: https://jsfiddle.net/rukaL1jm/
tego najbardziej w tym nie rozumiem, czemu ludzie sami sobie nie zrobią reducerów, skoro to zwykły design pattern, nie trzeba do tego całej biblioteki (chociaż z korzystania Reduxa płynie jedna zaleta - dobrze rozwinięty ekosystem (choćby fakt, że są dodatkowe biblioteki do niego, są DevToolsy itp.). Okej, można napisać Reduxa w kilka linijek, ale nie będzie to kompatybilne z całym reduxowym ekosystemem. Więc mocą Reduxa jest ekosystem raczej, a nie sama biblioteka.

Ale...

Redux to udany... proof of concept. Patrząc na ogólne założenia architektury to nie ma do czego się przyczepić. Patrzyłem na inne projekty Dana Abramova i też - gość ma bardzo słuszne podejście przywiązywania wagi do decouplingu, do tworzenia reużywalnych niezależnych od kontekstu bibliotek (np. Redux powstał w ekosystemie Reacta, ale można go używać wszędzie, bo łączenia Reduxa z Reactem są bardzo mądrze wydzielone do osobnej biblioteki. Podobnie jest w bibliotece do drag'n'drop Abramova, która też ma wydzielony rdzeń, który nawet nie jest zależny od przeglądarki:
https://github.com/react-dnd/react-dnd/tree/master/packages/dnd-core

To są naprawdę dobre założenia.

A sam Redux tak czy siak edukuje całe rzesze programistów o zasadach programowania funkcyjnego, wartości niemutowalności, o zaletach event sourcingu czy CQRS...

Na pewno Redux ma swoj rolę w krzewieniu wiedzy ogólnoprogramistycznej.

Tym niemniej Logo też ma dużą wartość edukacyjną. Czy to znaczy, że mamy robić w nim duże aplikacje?

No właśnie....

Więc co zamiast Reduxa?

Tworzę juz własne rozwiązanie. Nazywa się Vistate i jest utrzymane w stylu OOP.  Pozwala na tworzenie całej hierarchii inteligentnych modeli.

Oczywiście, Redux był jedną z inspiracji dla mnie w tworzeniu własnego rozwiązania, tym niemniej mam wrażenie, że ten sam cel (łatwe panowanie nad zmianami stanu w aplikacji) można zrobić inaczej, bardziej wygodniej, w bardziej elegancki sposób...

Swoją drogą widziałem Mobx, który realizuje zdaje się podobne założenia, które ja wdrażam w swojej bibliotece (coś jak Redux, ale OOP), ale jak spojrzałem w ich kod źródłowy, to mam wrażenie, że jest to przeinżynierowane. Trochę odwrotność Reduxa - Redux jest prostą biblioteką, którą się trudno obsługuje. A Mobx wydaje się być skomplikowaną biblioteką, którą się łatwo obsługuje.

No dobra, a czy nie można mieć obu rzeczy? Łatwą obsługę i prostotę implementacji? (nie lubię bibliotek ze skomplikowanym kodem, bo nauczyłem się już, że takie biblioteki ciężko się debuguje, bo zawsze ci wyskoczy błąd ze środka biblioteki i musisz i tak debugować cała bibliotekę).

Dlatego robię po swojemu.

Komentarze

Prześlij komentarz

Popularne posty z tego bloga

Ściemy z ogłoszeń o pracę

Jak nie sprawdzać wiedzy technicznej: platformy online

Jak zrobić prostą grę w JavaScript?