DDD nezačína priečinkom `domain`
Eric Evans predstavuje DDD ako súbor vzorov a definícií pre prácu s doménovými modelmi, zatiaľ čo Martin Fowler zdôrazňuje modelovanie zložitých domén a rozvoj spoločného jazyka medzi vývojármi a doménovými expertmi. [1][2][4]
Štruktúra `domain/application/infrastructure` teda sama osebe neznamená DDD. Kód môže mať dokonale pomenované priečinky a pritom obsahovať iba DTO a procedurálnu logiku. Strategické DDD možno používať aj bez kanonickej vrstvenej štruktúry.
Strategické DDD a taktické DDD pracujú na rôznych úrovniach
Strategické DDD rieši rozdelenie väčšej domény na subdomény a Bounded Contexts a ich vzťahy. Microsoft opisuje doménovú analýzu ako identifikáciu subdomén a obmedzených kontextov, zatiaľ čo Fowler označuje Bounded Context za centrálny strategický vzor. [3][7]
Taktické DDD pracuje vnútri konkrétneho kontextu a zahŕňa napríklad Entities, Value Objects, Aggregates a Domain Services. Microsoft výslovne oddeľuje strategickú analýzu od taktického modelovania. [8]
Vo frontende je často lepšie začať strategickým návrhom a až potom rozhodnúť, ktoré kontexty skutočne potrebujú bohatý taktický model.
Bounded Context nie je technická vrstva
Fowler opisuje Bounded Context ako hranicu, vnútri ktorej zostáva model konzistentný a pojmy majú jednoznačný význam. Rovnaký pojem, napríklad `Customer` alebo `Product`, môže mať v rôznych kontextoch odlišný význam. [3]
Preto `frontend`, `backend`, `React app`, `route` ani `micro-frontend` nie sú automaticky Bounded Contexts. Hranice vychádzajú z doménového modelu a jazyka, nie z technológie. Praktické zdroje o frontendovom DDD upozorňujú na rovnakú zámenu. [15][16]
Kedy DDD vo frontende dáva zmysel
| Signál | Smer | Prečo |
|---|---|---|
| Veľa meniacich sa biznisových pravidiel | DDD | Doménový model bráni rozptýleniu pravidiel |
| Rovnaké pojmy znamenajú v rôznych častiach produktu niečo iné | DDD | Bounded Contexts umožňujú viac konzistentných modelov |
| Spolupracuje viac tímov a doménových expertov | DDD | Ubiquitous Language znižuje nejednoznačnosť |
| Jednoduché CRUD a formuláre | Jednoduchšia modularita | Náklady taktického DDD môžu prevýšiť prínos |
| Frontend prevažne zrkadlí API | Jednoduchšia modularita | Je málo vlastnej klientovej doménovej logiky |
| Malá aplikácia s jednou konzistentnou doménou | Jednoduchšia modularita | Ďalšie hranice a vrstvy môžu priniesť malú hodnotu |
Najsilnejším signálom sú zložité a často sa meniace biznisové pravidlá na klientovi: konfigurátory, viacstupňové procesy, pricing, oprávnenia, prechody stavov, workflow alebo rozdielne modely rovnakého pojmu v rôznych častiach produktu.
DDD je užitočné aj vtedy, keď na veľkom produkte pracuje viac tímov a rovnaké slová majú v rôznych oblastiach iný význam. Bounded Contexts sú určené práve na správu viacerých konzistentných modelov. [3]
DDD Crew odporúča najprv pochopiť doménu, identifikovať strategicky dôležité subdomény, potom definovať zodpovednosti Bounded Contexts a až následne model kódovať. [10]
Kedy sa DDD stáva zbytočne zložitým
Ak frontend hlavne načítava dáta, zobrazuje ich, upravuje formuláre a odosiela jednoduché CRUD príkazy bez významnej biznisovej logiky na klientovi, kompletná sada taktických vzorov DDD zvyčajne nerieši skutočný problém.
Microsoft výslovne uvádza, že pre jednoduchý CRUD kontext môže stačiť anemický dátový model a zložitejšie vzory DDD nemusia stáť za náklady. Bohatší model je vhodnejší tam, kde existuje veľa meniacich sa biznisových pravidiel. [9]
Rovnaké kritérium platí aj vo frontende: zložitosť architektúry má zodpovedať zložitosti domény, nie technickým ambíciám tímu.
Ubiquitous Language má byť viditeľný aj v UI kóde
Ubiquitous Language je spoločný a presný jazyk vytváraný vývojármi a doménovými expertmi okolo modelu. Fowler zdôrazňuje, že sa má vyvíjať spolu s porozumením doméne. [4]
Vo frontende by názvy use case, akcií, typov, modulov, obrazoviek a stavov mali používať biznisový slovník vždy, keď vyjadrujú doménové správanie.
Ak biznis hovorí `approveApplication`, ale kód používa `setFlag2` alebo `handleData`, kód prestáva byť zrozumiteľným vyjadrením doménového jazyka.
Veľký frontend organizujte podľa domén, nie iba podľa typov súborov
Fowler uvádza, že štruktúra najvyššej úrovne `view/model/data` môže stačiť pri menších systémoch, ale s rastom je často lepšie mať top-level moduly podľa domén, ktoré si vo vnútri zachovávajú vlastné vrstvy. [5]
Aktuálna dokumentácia Nx ukazuje podobný smer: priečinky môžu tvoriť hranice ownershipu domén a knižnice v doméne možno klasifikovať ako `feature`, `ui`, `data-access` a `util`. [12]
Praktická štruktúra teda môže vyzerať ako `libs/orders/...`, `libs/billing/...`, `libs/identity/...` namiesto jedného globálneho stromu `components/`, `services/`, `models/`.
Oddeľte prezentačné správanie od doménového správania
Fowler opisuje oddelenie prezentácie, doménovej logiky a prístupu k dátam ako účinnú modularizáciu. UI kód sa tiež zvyčajne testuje ťažšie, preto má doménová logika mimo prezentácie výhodu. [5][6]
Frontendový komponent by mal primárne renderovať, obsluhovať UI udalosti a delegovať operácie. Pravidlá ako či možno objednávku zrušiť, ako vypočítať zľavu alebo aký prechod stavu je povolený, majú mať explicitné miesto mimo JSX, šablón alebo komponentových tried.
To neznamená zákaz prezentačnej logiky. Validácia pohľadu, viditeľnosť, lokálny focus alebo animácia sú iný druh logiky než biznisové pravidlá.
Praktické vrstvy v jednom frontendovom kontexte
| Vrstva | Zodpovednosť | Príklady |
|---|---|---|
| presentation / ui | Renderovanie a správanie rozhrania | components, routes, view state |
| application | Koordinácia use case | commands, use cases, orchestration |
| domain | Doménové pravidlá, pojmy a invarianty | entities, value objects, policies |
| infrastructure / data-access | Technické integrácie | HTTP, storage, SDKs, mappers |
DDD nepredpisuje povinnú štruktúru priečinkov. Oddelenie `presentation`, `application`, `domain` a `infrastructure` je praktická interpretácia separácie zodpovedností, nie formálna požiadavka Evansa. [1][5]
Vrstva domain môže obsahovať pravidlá, pojmy a správanie nezávislé od frameworku; application koordinuje use case; infrastructure adaptuje HTTP, storage a externé SDK; presentation obsahuje komponenty, routing a čisto UI stav.
API model a doménový model frontendu nemusia byť rovnaké
Bounded Context môže mať vlastný model určitého pojmu a rôzne kontexty môžu mapovať medzi rozdielnymi reprezentáciami. Fowler používa `Customer` a `Product` ako typické príklady pojmov s odlišným významom podľa kontextu. [3]
Backendové DTO preto nemusí prúdiť priamo do každého komponentu. Mapper alebo adapter môže transportný kontrakt previesť do modelu konkrétneho frontendového kontextu.
Takáto hranica je najcennejšia, keď API používa viac klientov, je legacy, kombinuje viac domén alebo sa vyvíja nezávisle. Pri jednoduchom CRUD endpointe môže byť ďalšia mapping vrstva zbytočná.
Entities, Value Objects a Aggregates používajte selektívne
DDD rozlišuje napríklad Entities, Value Objects, Services a Aggregates. Fowler ich uvádza ako súčasť Evansovho slovníka a Microsoft opisuje agregáty ako taktický vzor pre udržiavanie konzistencie modelu. [2][8]
Frontend by nemal kopírovať backendový model 1:1 iba kvôli rovnakým triedam. Value Object je užitočný pre `Money`, `DateRange` alebo `Email`, ak chráni skutočné invarianty. Aggregate dáva zmysel, ak klient reálne potrebuje strážiť pravidlá konzistencie.
Ak typ slúži len ako dáta pre tabuľku, jednoduchý TypeScript typ môže byť lepší než Entity, Factory, Repository a Service.
UI stav nie je to isté ako doménový stav
React považuje organizáciu stavu za návrhový problém a odporúča vyhýbať sa redundantnému alebo duplicitnému stavu. Je to dobrý technický základ, ale reducery, stores alebo signals samy osebe nevytvárajú doménový model. [14]
Stav ako `isModalOpen`, aktívna záložka alebo pozícia scrollu patrí prezentácii. Životný cyklus objednávky, povolené prechody procesu alebo pravidlá konfigurátora môžu patriť do doménového modelu.
Oddelenie týchto kategórií obmedzuje globálne stores, ktoré miešajú serverové dáta, biznisové správanie a UI detaily.
Hranice treba vynucovať, nie iba dokumentovať
Nx umožňuje definovať projektové tagy a deklaratívne obmedzenia závislostí, napríklad blokovať importy medzi scope alebo typmi knižníc. `@nx/enforce-module-boundaries` môže importy kontrolovať počas lintovania. [11]
Nx podporuje aj viac dimenzií tagov, takže možno samostatne modelovať `scope`, typ knižnice, stabilitu alebo client/server aspekty. [13]
Rozhodnutia DDD sa tak môžu stať pravidlami CI: `billing` neimportuje interné časti `identity`, `ui` nezávisí od `data-access` a `domain` zostáva nezávislý od frameworku.
Frontend a backend môžu zdieľať doménu bez identického modelu
Bounded Context je hranicou modelu a jazyka, preto by sa nemal automaticky kresliť pozdĺž sieťovej hranice medzi prehliadačom a serverom. Praktické materiály o frontendovom DDD zdôrazňujú, že kontexty môžu prechádzať technickými vrstvami a byť realizované spoločne frontendom aj backendom. [15][16]
Klientská reprezentácia sa napriek tomu môže líšiť od serverovej kvôli odlišným potrebám interakcie, lokálneho stavu a prezentácie. Dôležitá je správna sémantika a explicitné mapovanie, nie kopírovanie tried.
Micro-frontend tiež nemá vzniknúť iba preto, že existuje Bounded Context. Doménová hranica a hranica deployovateľného artefaktu sú dve odlišné rozhodnutia.
Testovateľnosť je silný dôvod na izoláciu doménovej logiky
Fowler uvádza testovateľnosť ako výhodu oddelenia prezentácie od domény. Logiku mimo UI možno testovať bez renderovania komponentov a bez závislosti od detailov rozhrania. [5][6]
Vo frontende to umožňuje rýchle testy pravidiel, Value Objects, use case a prechodov stavov ako bežného TypeScriptu alebo JavaScriptu. Komponentové testy zostávajú potrebné, ale nemusia byť jediným miestom overovania biznisových pravidiel.
Varovným signálom je stav, keď každá zmena biznisového pravidla vyžaduje mount celej komponenty a mock routera, store, HTTP a browser API.
Ako zaviesť DDD do existujúceho frontendu bez veľkého rewrite
DDD Crew odporúča iteratívny proces: pochopiť doménu, určiť dôležité subdomény, definovať zodpovednosti Bounded Contexts a až potom kódovať model. [10]
V existujúcom frontende je bezpečnejšie vybrať jednu problémovú oblasť, pomenovať jej jazyk, stanoviť hranicu, oddeliť prezentáciu od pravidiel, definovať verejné API modulu a až potom migrovať ďalšie funkcie.
Celú aplikáciu netreba prerábať. DDD možno použiť tam, kde biznisová zložitosť vráti náklady na modelovanie, a jednoduché oblasti ponechať ako ľahšie feature moduly.
- Začnite biznisovým problémom, nie priečinkami.
- Identifikujte pojmy, pravidlá a nejednoznačné termíny.
- Definujte jeden Bounded Context a jeho verejný kontrakt.
- Oddeľte doménové pravidlá od komponentov a transportných DTO.
- Pridávajte iba taktické vzory, ktoré riešia konkrétnu zložitosť.
- Zapíšte hranice ako lint alebo CI pravidlá.
- Merajte závislosti, cykly, regresie a náklady priečnych zmien.
- Nemigrujte jednoduché CRUD oblasti iba kvôli architektonickej symetrii.

