DDD nezačíná složkou `domain`
Eric Evans představuje DDD jako soubor vzorů a definic pro práci s doménovými modely, zatímco Martin Fowler zdůrazňuje modelování složitých domén a rozvoj společného jazyka mezi vývojáři a doménovými experty. [1][2][4]
Struktura `domain/application/infrastructure` tedy sama o sobě neznamená DDD. Kód může mít perfektně pojmenované složky a přitom obsahovat jen DTO a procedurální logiku. Strategické DDD lze použít i bez kanonické vrstvené struktury.
Strategické DDD a taktické DDD pracují na různých úrovních
Strategické DDD řeší rozdělení větší domény na subdomény a Bounded Contexts a jejich vztahy. Microsoft popisuje doménovou analýzu jako identifikaci subdomén a omezených kontextů, zatímco Fowler označuje Bounded Context za centrální strategický vzor. [3][7]
Taktické DDD pracuje uvnitř konkrétního kontextu a zahrnuje například Entities, Value Objects, Aggregates a Domain Services. Microsoft výslovně odděluje strategickou analýzu od taktického modelování. [8]
Ve frontendu je často lepší začít strategickým návrhem a až potom rozhodnout, které kontexty skutečně potřebují bohatý taktický model.
Bounded Context není technická vrstva
Fowler popisuje Bounded Context jako hranici, uvnitř které zůstává model konzistentní a pojmy mají jednoznačný význam. Stejný pojem, například `Customer` nebo `Product`, může mít v různých kontextech odlišný význam. [3]
Proto `frontend`, `backend`, `React app`, `route` ani `micro-frontend` nejsou automaticky Bounded Contexts. Hranice vycházejí z doménového modelu a jazyka, ne z technologie. Praktické zdroje o frontendovém DDD upozorňují na stejnou záměnu. [15][16]
Kdy DDD ve frontendu dává smysl
| Signál | Směr | Proč |
|---|---|---|
| Mnoho měnících se byznysových pravidel | DDD | Doménový model brání rozptýlení pravidel |
| Stejné pojmy znamenají v různých částech produktu něco jiného | DDD | Bounded Contexts umožňují několik konzistentních modelů |
| Spolupracuje více týmů a doménových expertů | DDD | Ubiquitous Language snižuje nejednoznačnost |
| Jednoduché CRUD a formuláře | Jednodušší modularita | Náklady taktického DDD mohou převýšit přínos |
| Frontend převážně zrcadlí API | Jednodušší modularita | Je málo vlastní klientské doménové logiky |
| Malá aplikace s jednou konzistentní doménou | Jednodušší modularita | Další hranice a vrstvy mohou přinést malou hodnotu |
Nejsilnějším signálem jsou složitá a často se měnící byznysová pravidla na klientovi: konfigurátory, vícekrokové procesy, pricing, oprávnění, přechody stavů, workflow nebo rozdílné modely stejného pojmu v různých částech produktu.
DDD je také užitečné, když na velkém produktu pracuje více týmů a stejná slova mají v různých oblastech jiný význam. Bounded Contexts jsou určeny právě pro správu několika konzistentních modelů. [3]
DDD Crew doporučuje nejprve porozumět doméně, identifikovat strategicky důležité subdomény, potom definovat odpovědnosti Bounded Contexts a teprve následně model kódovat. [10]
Kdy se DDD stává zbytečně složitým
Pokud frontend hlavně načítá data, zobrazuje je, upravuje formuláře a odesílá jednoduché CRUD příkazy bez významné byznysové logiky na klientovi, kompletní sada taktických vzorů DDD obvykle neřeší skutečný problém.
Microsoft výslovně uvádí, že pro jednoduchý CRUD kontext může stačit anemický datový model a složitější vzory DDD nemusí stát za náklady. Bohatší model je vhodnější, když existuje mnoho měnících se byznysových pravidel. [9]
Stejné kritérium platí i ve frontendu: složitost architektury má odpovídat složitosti domény, ne technickým ambicím týmu.
Ubiquitous Language má být viditelný i v UI kódu
Ubiquitous Language je společný a přesný jazyk vytvářený vývojáři a doménovými experty kolem modelu. Fowler zdůrazňuje, že se má vyvíjet spolu s porozuměním doméně. [4]
Ve frontendu by názvy use case, akcí, typů, modulů, obrazovek a stavů měly používat byznysový slovník vždy, když vyjadřují doménové chování.
Pokud byznys říká `approveApplication`, ale kód používá `setFlag2` nebo `handleData`, kód přestává být srozumitelným vyjádřením doménového jazyka.
Velký frontend organizujte podle domén, ne jen podle typů souborů
Fowler uvádí, že struktura nejvyšší úrovně `view/model/data` může stačit u menších systémů, ale s růstem je často lepší mít top-level moduly podle domén, které si uvnitř zachovávají vlastní vrstvy. [5]
Aktuální dokumentace Nx ukazuje podobný směr: složky mohou tvořit hranice ownershipu domén a knihovny uvnitř domény lze klasifikovat jako `feature`, `ui`, `data-access` a `util`. [12]
Praktická struktura tedy může vypadat jako `libs/orders/...`, `libs/billing/...`, `libs/identity/...` místo jednoho globálního stromu `components/`, `services/`, `models/`.
Oddělte prezentační chování od doménového chování
Fowler popisuje oddělení prezentace, doménové logiky a přístupu k datům jako účinnou modularizaci. UI kód se také obvykle testuje obtížněji, proto má doménová logika mimo prezentaci výhodu. [5][6]
Frontendová komponenta by měla primárně renderovat, obsluhovat UI události a delegovat operace. Pravidla jako zda lze objednávku zrušit, jak spočítat slevu nebo jaký přechod stavu je povolený, mají mít explicitní místo mimo JSX, šablony nebo komponentní třídy.
To neznamená zákaz prezentační logiky. Validace pohledu, viditelnost, lokální focus nebo animace jsou jiný typ logiky než byznysová pravidla.
Praktické vrstvy uvnitř jednoho frontendového kontextu
| Vrstva | Odpovědnost | Příklady |
|---|---|---|
| presentation / ui | Renderování a chování rozhraní | components, routes, view state |
| application | Koordinace use case | commands, use cases, orchestration |
| domain | Doménová pravidla, pojmy a invarianty | entities, value objects, policies |
| infrastructure / data-access | Technické integrace | HTTP, storage, SDKs, mappers |
DDD nepředepisuje povinnou strukturu složek. Oddělení `presentation`, `application`, `domain` a `infrastructure` je praktická interpretace separace odpovědností, ne formální požadavek Evansa. [1][5]
Vrstva domain může obsahovat pravidla, pojmy a chování nezávislé na frameworku; application koordinuje use case; infrastructure adaptuje HTTP, storage a externí SDK; presentation obsahuje komponenty, routing a čistě UI stav.
API model a doménový model frontendu nemusí být stejné
Bounded Context může mít vlastní model určitého pojmu a různé kontexty mohou mapovat mezi různými reprezentacemi. Fowler používá `Customer` a `Product` jako typické příklady pojmů s odlišným významem podle kontextu. [3]
Backendové DTO proto nemusí proudit přímo do každé komponenty. Mapper nebo adapter může transportní kontrakt převést do modelu konkrétního frontendového kontextu.
Taková hranice je nejcennější, když API používá více klientů, je legacy, kombinuje více domén nebo se vyvíjí nezávisle. U jednoduchého CRUD endpointu může být další mapping vrstva zbytečná.
Entities, Value Objects a Aggregates používejte selektivně
DDD rozlišuje například Entities, Value Objects, Services a Aggregates. Fowler je uvádí jako součást Evansova slovníku a Microsoft popisuje agregáty jako taktický vzor pro udržování konzistence modelu. [2][8]
Frontend by neměl kopírovat backendový model 1:1 jen kvůli stejným třídám. Value Object je užitečný pro `Money`, `DateRange` nebo `Email`, pokud chrání skutečné invarianty. Aggregate dává smysl, pokud klient skutečně potřebuje hlídat konzistenční pravidla.
Pokud typ slouží jen jako data pro tabulku, může být jednoduchý TypeScript typ lepší než Entity, Factory, Repository a Service.
UI stav není totéž co doménový stav
React považuje organizaci stavu za návrhový problém a doporučuje vyhnout se redundantnímu nebo duplicitnímu stavu. Je to dobrý technický základ, ale reducery, store nebo signals samy o sobě nevytvářejí doménový model. [14]
Stav jako `isModalOpen`, aktivní záložka nebo pozice scrollu patří prezentaci. Životní cyklus objednávky, povolené přechody procesu nebo pravidla konfigurátoru mohou patřit do doménového modelu.
Oddělení těchto kategorií omezuje globální store, které míchají serverová data, byznysové chování a UI detaily.
Hranice je potřeba vynucovat, ne jen dokumentovat
Nx umožňuje definovat projektové tagy a deklarativní omezení závislostí, například blokovat importy mezi scope nebo typy knihoven. `@nx/enforce-module-boundaries` může importy kontrolovat během lintování. [11]
Nx podporuje i více dimenzí tagů, takže lze zvlášť modelovat `scope`, typ knihovny, stabilitu nebo client/server aspekty. [13]
Rozhodnutí DDD se tak mohou stát pravidly CI: `billing` neimportuje interní části `identity`, `ui` nezávisí na `data-access` a `domain` zůstává nezávislý na frameworku.
Frontend a backend mohou sdílet doménu bez identického modelu
Bounded Context je hranicí modelu a jazyka, proto by se neměl automaticky kreslit podél síťové hranice mezi prohlížečem a serverem. Praktické materiály o frontendovém DDD zdůrazňují, že kontexty mohou procházet technickými vrstvami a být realizovány společně frontendem i backendem. [15][16]
Klientská reprezentace se přesto může lišit od serverové kvůli jiným potřebám interakce, lokálního stavu a prezentace. Důležitá je správná sémantika a explicitní mapping, ne kopírování tříd.
Micro-frontend také nemá vzniknout jen proto, že existuje Bounded Context. Doménová hranice a hranice deployovatelného artefaktu jsou dvě různá rozhodnutí.
Testovatelnost je silný důvod pro izolaci doménové logiky
Fowler uvádí testovatelnost jako výhodu oddělení prezentace od domény. Logiku mimo UI lze testovat bez renderování komponent a bez závislosti na detailech rozhraní. [5][6]
Ve frontendu to umožňuje rychlé testy pravidel, Value Objects, use case a přechodů stavů jako běžného TypeScriptu nebo JavaScriptu. Komponentní testy zůstávají potřebné, ale nemusí být jediným místem ověřování byznysových pravidel.
Varovným signálem je stav, kdy každá změna byznysového pravidla vyžaduje mount celé komponenty a mock routeru, store, HTTP a browser API.
Jak zavést DDD do existujícího frontendu bez velkého rewrite
DDD Crew doporučuje iterativní proces: porozumět doméně, určit důležité subdomény, definovat odpovědnosti Bounded Contexts a teprve potom kódovat model. [10]
V existujícím frontendu je bezpečnější vybrat jednu problémovou oblast, pojmenovat její jazyk, stanovit hranici, oddělit prezentaci od pravidel, definovat veřejné API modulu a až poté migrovat další funkce.
Celou aplikaci není nutné převádět. DDD lze použít tam, kde byznysová složitost vrátí náklady na modelování, a jednoduché oblasti ponechat jako lehčí feature moduly.
- Začněte byznysovým problémem, ne složkami.
- Identifikujte pojmy, pravidla a nejednoznačné termíny.
- Definujte jeden Bounded Context a jeho veřejný kontrakt.
- Oddělte doménová pravidla od komponent a transportních DTO.
- Přidávejte jen taktické vzory, které řeší konkrétní složitost.
- Zapište hranice jako lint nebo CI pravidla.
- Měřte závislosti, cykly, regrese a náklady průřezových změn.
- Nemigrujte jednoduché CRUD oblasti jen kvůli architektonické symetrii.

