Praktický návod

Jak rozdělit monolitickou aplikaci na moduly

Monolit nemusí být problém. Rozděl ho tam, kde tě změny opravdu bolí, a dělej to po jednom bezpečném kroku.

25 minut · Architektura

Nejdřív stručně

Modul není mikroslužba

Monolit je jedna nasaditelná aplikace. Může mít ale dobré vnitřní hranice. Modul je část kódu, která drží pohromadě jeden byznysový celek, třeba objednávky nebo sklad.

Cílem není vytvořit co nejvíc složek ani hned přejít na mikroslužby. Cílem je snížit coupling: změna ve skladu nemá rozbít fakturaci jen proto, že spolu omylem sdílejí interní detaily.

Připrav si

Co potřebuješ před prvním přesunem

Nejdřív si zjisti, kde aplikace nejvíc bolí. To bývá lepší začátek než kreslit moduly podle databázových tabulek.

  • Jeden často měněný celek, například objednávky, katalog nebo fakturace.
  • Seznam míst, která se při jeho změně obvykle upravují. Kontrolery, služby, entity, šablony i integrační kód.
  • Aspoň základní automatické testy kolem vybraného celku. Bez nich nepoznáš, zda přesun něco nerozbil.
  • Dohodu týmu, že modul bude mít veřejné vstupy a ostatní části nebudou sahat do jeho interních tříd.

Kroky 1 až 3

Rozděl monolit po malých řezech

Přesouvej po funkci, ne po typech souborů. Cílem je samostatný celek, který umí udělat svou práci.

1. Najdi první bounded context

  1. Vyber oblast s vlastním jazykem a pravidly. Objednávka, produkt a faktura jsou často lepší hranice než „controllers“ a „entities“.
  2. Napiš, co do oblasti patří a co už ne. Například objednávka může požádat o platbu, ale nemá znát interní tabulky platební brány.
  3. Začni jedním modulem. Pět nových modulů bez jasné zodpovědnosti jen přesune zmatek do nových složek.
mkdir -p src/Order
Oficiální Symfony doporučení pro organizaci kódu

2. Vytvoř malý veřejný vstup modulu

  1. Sepiš, co smí zbytek aplikace od modulu chtít. Třeba PlaceOrder nebo CancelOrder. To jsou jeho veřejné use-casy.
  2. Kontroler ani jiný modul nemá přímo měnit entity uvnitř modulu. Zavolá veřejný use-case a dostane výsledek.
  3. Data mezi moduly drž stručná. Předej ID, hodnoty a výsledek, ne celý graf objektů napříč aplikací.
Oficiální Symfony dokumentace k propojení služeb

3. Přesuň jednu funkci včetně pravidel

  1. Vyber jeden konkrétní use-case. Přesuň jeho aplikační službu, doménová pravidla a testy společně.
  2. Staré volání chvíli zachovej jako tenkou přechodovou vrstvu. Teprve až jsou volající převedení, odstraň ho.
  3. Závislost ven z modulu dej přes rozhraní. Modul si tím nenechá vnutit konkrétní databázi, e-mail ani externí SDK.
php bin/phpunit --testsuite=Order
Oficiální Symfony dokumentace k autowiringu

Krok 4

Ověř, že modul drží pohromadě

Dobrý první modul usnadní příští změnu. Nemusí být dokonalý ani úplně oddělený od všeho ostatního.

  1. Spusť testy vybraného celku

    Nejdřív ověř jen funkci, kterou jsi přesouval. Potom spusť celou sadu testů.

    php bin/phpunit
  2. Vyhledej přímé přístupy dovnitř modulu

    Prohlédni importy z jiných částí aplikace. Nemají záviset na interních třídách modulu, pokud to není jasně domluvená výjimka.

    rg "App\\Order\\" src
  3. Udělej malou změnu v pravidle

    Třeba změň podmínku, kdy lze objednávku zrušit. Sleduj, zda upravuješ hlavně modul a jeho testy, ne náhodné soubory po celé aplikaci.

Když to zlobí

Nejčastější chyby

Vznikl nový modul, ale všechno stále volá staré služby

Nejdřív převeď jednoho konkrétního volajícího na veřejný use-case modulu. Pak další. Bez postupného přesměrování zůstane nový modul jen kopií kódu.

Moduly sdílejí databázové entity napříč hranicí

Přestaň předávat celou entitu. Druhému modulu dej ID nebo malé data. Když potřebuje více, zvaž vlastní dotaz nebo veřejný aplikační vstup.

Rozdělení zastavilo vývoj funkcí

Zmenši řez. Cílem není vyčistit celý modul za týden, ale bezpečně přesunout jednu hodnotnou funkci mezi běžnými změnami.

Každý modul má vlastní kopii stejného pravidla

Než vytáhneš společnou knihovnu, ověř, že jde opravdu o stejné pravidlo. Podobný kód může mít jiný byznysový význam; předčasné sdílení vytváří další coupling.

Hotovo

Monolit má první jasnou hranici.

Další moduly přidávej až ve chvíli, kdy je k tomu skutečný důvod. Jedna srozumitelná hranice je cennější než deset složek s novými názvy.

Zavolejte mi

Zavolám vám následující pracovní den mezi 9:00 a 17:00.

Můžete mi také zavolat rovnou.

+420 605 181 728

Nechte mi telefonní číslo a pošlete žádost o zpětné zavolání.

Odesláním souhlasíte se zpracováním údajů pro vyřízení žádosti.