Když jsme loni na podzim uvažovali, jakým tématem reprezentovat naši firmu na Barcampu v Hradci, chtěli jsme, aby to bylo něco unikátního. Něco, na co jsme si v MoroSystems přišli sami a myslíme si, že to děláme dobře. A došli jsme k tomu, že strukturování aplikace do modulů je něco, čemu jsme věnovali hodně času a úsilí, a že jsme vytvořili něco, o co bychom se rádi podělili. Výsledkem byla poměrně úspěšná, byť velmi technická přednáška Strukturování velké aplikace v Reactu.
Bohužel, všechno, na co jsme si přišli, se nemůže vejít do dvaceti minut. Když jsem si nedávno uvědomil, jak jsme se za poslední rok posunuli od několika obrazovkových a core modulů k ekosystému modulů, submodulů, business modulů a parametrizovaných modulů, seznal jsem, že to není ani téma na jeden článek. V této sérii bych Vám rád představil nejen to, jak moduly používáme, ale i proč, jak jsme k tomu došli a také co by se dalo udělat jinak, možná lépe. Budu se snažit, abyste si z ní odnesli nejen to, jak náš přístup použít, ale i v čem je dobrý, kde má své slabé stránky a abyste byli schopni si ho upravit pro své účely.
To, o čem budu psát, samozřejmě, není pouze mé dílo. Hlavní dík patří Tomáši Jílkovi, se kterým jsme celou tu věc upekli a který je autorem některých základních tezí. Kromě něj bych ale chtěl zmínit i kolegy z eBay týmu, kteří, ač si to pravděpodobně neuvědomují, svými většinou dobrými programátorskými návyky ovlivnili podobu výsledného systému.
Pozadí: Projekty a technologie
Náš systém modulů považuji za vcelku univerzálně použitelný, vznikl ovšem na projektech s určitými vlastnostmi, které je dobré si uvědomit v okamžiku, kdy se jej budeme snažit použít. V MoroSystems React používáme především v rámci zakázkového vývoje, naše aplikace jsou tedy typicky informační systémy. Charakteristické pro ně je, že jsou spíše datově než uživatelsky založené. Ve výsledku se skládají z většího množství obrazovek, které jsou však značně podobné. Zobrazují data. Sice různá data, ale často stejným způsobem: jsou tam tabulky, filtry, mají podobný layout apod. Vycházíme tedy z velkých aplikací s množstvím podobných stránek.
Pokud náš přístup ovlivňují projekty, tak technologie jej přímo určují. Pro účely této série je důležité, že React s Reduxem používáme tak, aby co nejvíce komponent bylo napojených. Pokud to jde, nenapojujeme rodičovskou komponentu, ale její děti. Výsledkem je to, že napojených komponent máme opravdu hodně. Taky máme poměrně hodně komponent, které sice nejsou napojené, ale obsahují napojené komponenty.
Druhá technologie, která nás hodně ovlivňuje, jsou ságy. Knihovnu redux-saga jsme zvolili proto, že je expresivnější než thunky (má vláknový model), ale pro programátory, z nichž valná většina pochází z prostředí Javy, je snáze pochopitelná než například RxJS. Práce se ságami přináší z hlediska modulů specifické problémy s čekáním na dokončení operace, o kterých později budu mluvit.
Pro úplnost bych ještě měl dodat, že používáme ES6 moduly (direktivy import a export) a celou aplikaci vytváříme pomocí webpacku. Je třeba zdůraznit, že ES6 moduly neodpovídají našim modulům, respektive jeden náš modul se typicky skládá z více ES6 modulů. Abych nemusel řešit přetížení termínů, budu ES6 moduly označovat jako soubory. Protože pro naše účely jsou to fakticky soubory na disku.
Modulární design
Prošli jsme si technická východiska. Co se týče východisek myšlenkových, celá naše snaha vychází z principů modulárního designu. Můžeme se bavit o různých programovacích paradigmatech, o tom, jestli objektově orientované programování je nebo není překonané, ale modulární design, kdy systém rozdělujeme do logických celků – modulů – s jasně definovaným rozhraním, které vzájemně neví o své vnitřní implementaci, bych v současné době považoval za všeobecně uznávanou praxi. Koneckonců, co jsou softwarové knihovny jiného než moduly? Osobně si myslím, že tento přístup je nezbytný pro údržbu každého většího systému, i když vždy můžeme polemizovat o tom, jak velké moduly mají být.
Proč usilovat o modulární aplikaci? My máme dva hlavní důvody. Zaprvé je to znovupoužitelnost. V okamžiku, kdy máme funkcionalitu zabalenou do modulu, můžeme ji použít na více místech. Druhým důvodem je logické oddělení. V okamžiku, kdy potřebujeme změnit kód modulu, nemusíme řešit všechna místa, kde se používá, stačí pouze, že se zachová jeho rozhraní. Podobně, když chceme použít modul, nemusíme řešit jeho vnitřní implementaci, stačí znát jeho rozhraní. To značně zjednodušuje práci programátorů, protože se můžou soustředit jen na jeden problém. Samozřejmě rozhraní modulů musí být dobře navržené.
Když navrhujeme moduly, hledáme právě tyto dvě vlastnosti – aby se dal použít na více místech a aby byl logicky oddělitelný. Když se na to podíváte z hlediska našich aplikací – více podobných obrazovek, tedy opakovaná funkcionalita – modulární design dává smysl.
Jack Hsu: Strukturování reduxových aplikací
I proto nás překvapilo, že se struktura JavaScriptových aplikací, alespoň zpočátku, modulárně moc neřešila. Typické bylo strukturovat aplikaci podle rolí objektů ve frameworku, tedy konkrétně pro React a Redux mít soubor nebo složku pro všechny generátory akcí, to samé pro reducer, komponenty, a podobně. Je jasné, že takový přístup může být vhodný pro malé projekty, například tutorialy, ale u velkého projektu to přece nemůže skončit jinak než jako velká hrouda bahna. S něčím takovým jsme nemohli pracovat.
V době, kdy jsme řešili, jak budeme strukturovat aplikaci, jsme narazili na článek Jacka Hsu Strukturování reduxových aplikací, který navrhuje aplikovat modulární design a vytvářet moduly podle funkcionality. Tento článek jsme vzali jako základ a ten jsme postupně upravovali podle našich potřeb. V příštím díle této série si proto představíme základní strukturu reduxového modulu, jak jsme ji převzali, použili a začali upravovat pro naše potřeby.
Napsat komentář