Czy reducer powinien zwracać Obserwable i Promisy?
Zastanawiam się, czy nie wywalić flagowej opcji z mojej biblioteki. A mianowicie fakt, że reducer może zwracać obserwable i opakowane w funkcję promisy.
Czyli teraz da się tak zrobić w Feedbacks:
albo:
Dlaczego chcę to wywalić?
No bo załóżmy, że moja biblioteka będzie używana w dużych projektach. Wtedy takie machinacje obserwablami czy zwracanie asynchronicznych funkcji bezpośrednio z reducerów mogłoby sprawić, że projekt stałby się trudniejszy w debugowaniu albo trudne byłoby robienie jakichś mocnych zmian w implementacji (ponieważ wszystko w środku byłoby sprzężone z tymi obserwablami).
Wpadłem na pomysł w jaki sposób mógłbym w bardziej elegancki sposób obsługiwać efekty uboczne.
Tzn. dalej reducer zwracałby efekt uboczny, tylko, że nie wprost obserwable/asynchroniczne funkcje, a raczej obiekt z parametrami efektu np.
(przy czym zrobię helpery do robienia "effect creatorów", ale to już drobiazg).
takie podejście (że efekt byłby scharakteryzowany przez typ i parametry i dopiero potem zamieniony na "prawdziwy" efekt) sprawiłoby, że efekty mogłyby być np. serializowane (co będzie miało podobne zalety, jakie ma fakt, jeśli akcje w Reduxie są serializowalne - można to np. wysyłać przez sieć, zapamiętywać gdzieś w logach, odtwarzać później itp.).
Samo mięso (rozwiązywanie obsserwabli i promisów) byłoby zachowane, tzn. ten sam ogólny model działania miałaby moja biblioteka, z tą różnicą, że nie moglibyście zwrócić obserwabla czy funkcji zwracającej Promise bezpośrednio z Reducera, tylko że najpierw musielibyście zwrócić efekt, a potem ten efekt byłby zamieniony na Obserwabla czy Promise.
Od strony użytkowania biblioteki byłby to dodatkowy krok, albo dodatkowe 2 kroki (zdefiniowanie effect creatora oraz napisanie funkcji, która zamienia efekt w obserwable/promise). Więc niby "więcej boilerplate'u" (więcej o pewnie jakieś 3-5 linijek), ale mimo wszystko czuję, że to będzie bardziej skalowalne.
Z drugiej strony dzięki takiemu parametrycznemu podejściu łatwiej można by było kontrolować całą aplikację (chcę zrobić też pattern matching dla efektów podobny do tego, który zrobiłem dla akcji). I cały projekt nabrał by pewnej spójności (ponieważ efekty by się obsługiwało analogicznie do akcji).
Ale jeszcze zobaczę, może da się do tego jeszcze w inny sposób podejść?
Teoretycznie mógłbym nie usuwać żadnego ficzera i zostawić zarówno parametryczne efekty jak i wprost zwracanie obserwabli/asynchronicznych funkcji wprost z reducerów, ale to już nie chodzi o technikalia (pod kątem implementacji mogą istnieć obydwie te opcje, nie ma problemów), tylko raczej o to, że:
"There should be one-- and preferably only one --obvious way to do it."
Tak to ludzie nie będą wiedzieli, jak mają robić, ew. zaczęliby stosować mało skalowalne design patterny w dużych projektach. Jak coś można zrobić to ludzie to zwykle robią bez zastanowienia się czy to jest właściwe. Widać co się stało z React. Ludzie do takiego componentDidMount wrzucają kompletnie wszystko, łącznie z waleniem requestów przez axiosa czy wrzucaniem tony rzeczy, które w komponentach nie powinny się znajdować. Redux-thunk też jest podobnie nadużywany i thunki to zwykle takie śmietniczki na kod.
Chciałbym jednak, żeby moja biblioteka pomagała ludziom pisać bardziej skalowalny kod.
Czyli teraz da się tak zrobić w Feedbacks:
function reducer(state, action) { return () => Promise.resolve(123); }
albo:
function reducer(state, action) { return Rx.interval(1000); }
Dlaczego chcę to wywalić?
No bo załóżmy, że moja biblioteka będzie używana w dużych projektach. Wtedy takie machinacje obserwablami czy zwracanie asynchronicznych funkcji bezpośrednio z reducerów mogłoby sprawić, że projekt stałby się trudniejszy w debugowaniu albo trudne byłoby robienie jakichś mocnych zmian w implementacji (ponieważ wszystko w środku byłoby sprzężone z tymi obserwablami).
Wpadłem na pomysł w jaki sposób mógłbym w bardziej elegancki sposób obsługiwać efekty uboczne.
Tzn. dalej reducer zwracałby efekt uboczny, tylko, że nie wprost obserwable/asynchroniczne funkcje, a raczej obiekt z parametrami efektu np.
{type: 'fetchData', params: {url: 'example.json'} }
(przy czym zrobię helpery do robienia "effect creatorów", ale to już drobiazg).
takie podejście (że efekt byłby scharakteryzowany przez typ i parametry i dopiero potem zamieniony na "prawdziwy" efekt) sprawiłoby, że efekty mogłyby być np. serializowane (co będzie miało podobne zalety, jakie ma fakt, jeśli akcje w Reduxie są serializowalne - można to np. wysyłać przez sieć, zapamiętywać gdzieś w logach, odtwarzać później itp.).
Samo mięso (rozwiązywanie obsserwabli i promisów) byłoby zachowane, tzn. ten sam ogólny model działania miałaby moja biblioteka, z tą różnicą, że nie moglibyście zwrócić obserwabla czy funkcji zwracającej Promise bezpośrednio z Reducera, tylko że najpierw musielibyście zwrócić efekt, a potem ten efekt byłby zamieniony na Obserwabla czy Promise.
Od strony użytkowania biblioteki byłby to dodatkowy krok, albo dodatkowe 2 kroki (zdefiniowanie effect creatora oraz napisanie funkcji, która zamienia efekt w obserwable/promise). Więc niby "więcej boilerplate'u" (więcej o pewnie jakieś 3-5 linijek), ale mimo wszystko czuję, że to będzie bardziej skalowalne.
Z drugiej strony dzięki takiemu parametrycznemu podejściu łatwiej można by było kontrolować całą aplikację (chcę zrobić też pattern matching dla efektów podobny do tego, który zrobiłem dla akcji). I cały projekt nabrał by pewnej spójności (ponieważ efekty by się obsługiwało analogicznie do akcji).
Ale jeszcze zobaczę, może da się do tego jeszcze w inny sposób podejść?
Teoretycznie mógłbym nie usuwać żadnego ficzera i zostawić zarówno parametryczne efekty jak i wprost zwracanie obserwabli/asynchronicznych funkcji wprost z reducerów, ale to już nie chodzi o technikalia (pod kątem implementacji mogą istnieć obydwie te opcje, nie ma problemów), tylko raczej o to, że:
"There should be one-- and preferably only one --obvious way to do it."
Tak to ludzie nie będą wiedzieli, jak mają robić, ew. zaczęliby stosować mało skalowalne design patterny w dużych projektach. Jak coś można zrobić to ludzie to zwykle robią bez zastanowienia się czy to jest właściwe. Widać co się stało z React. Ludzie do takiego componentDidMount wrzucają kompletnie wszystko, łącznie z waleniem requestów przez axiosa czy wrzucaniem tony rzeczy, które w komponentach nie powinny się znajdować. Redux-thunk też jest podobnie nadużywany i thunki to zwykle takie śmietniczki na kod.
Chciałbym jednak, żeby moja biblioteka pomagała ludziom pisać bardziej skalowalny kod.
Komentarze
Prześlij komentarz