Co je Domain-Driven Design?
Definice DDD
Domain-Driven Design (DDD) je přístup k vývoji softwaru, který se zaměřuje na modelování domény a její implementaci v kódu. Byl představen Ericem Evansem v jeho knize "Domain-Driven Design: Tackling Complexity in the Heart of Software" v roce 2003 [1].
Klíčové aspekty DDD:
- Doména (Domain) - Oblast znalostí, problémů a aktivit, na kterou se aplikace zaměřuje [2]. Doména představuje specifickou oblast, kterou se software snaží modelovat a řešit.
- Ubiquitous Language - Společný jazyk používaný vývojáři a doménovými experty [3]. Tento jazyk eliminuje nedorozumění a zajišťuje, že všichni účastníci projektu mluví stejným jazykem.
- Bounded Context - Jasně definovaná hranice, ve které je model platný [4]. Bounded Context pomáhá rozdělit složité domény do menších, lépe zvládnutelných částí.
- Model-Driven Design - Návrh softwaru založený na modelu domény [5]. Model je zjednodušenou reprezentací domény, která zachycuje její klíčové aspekty.
Historie a vývoj DDD
Domain-Driven Design byl představen Ericem Evansem v roce 2003. Od té doby se stal populárním přístupem k vývoji softwaru, zejména pro složité aplikace s bohatou doménou. V průběhu let se DDD vyvíjel a byly představeny nové koncepty a techniky [6].
V posledních letech se DDD často kombinuje s dalšími architektonickými vzory, jako je CQRS (Command Query Responsibility Segregation) a Event Sourcing, což vede k ještě výkonnějším a flexibilnějším architekturám [7] [8].
Základní principy DDD
Domain-Driven Design je založen na několika základních principech:
- Zaměření na doménu - DDD se zaměřuje na doménu a doménovou logiku. Technické detaily jsou sekundární.
- Ubiquitous Language - DDD používá společný jazyk mezi vývojáři a doménovými experty, který je používán v kódu, dokumentaci a komunikaci.
- Bounded Context - DDD rozděluje složité domény do menších, jasně definovaných kontextů s explicitními hranicemi.
- Model-Driven Design - DDD používá model jako základ pro návrh softwaru. Model je zjednodušenou reprezentací domény.
- Strategic Design - DDD poskytuje nástroje pro strategický návrh, který pomáhá definovat hranice mezi různými částmi systému.
- Tactical Design - DDD poskytuje vzory pro taktický návrh, které pomáhají implementovat doménový model v kódu.
Strategický design (Strategic Design)
Strategický design se zabývá širším kontextem systému a definuje, jak různé části systému spolu interagují. Klíčové koncepty strategického designu zahrnují:
- Bounded Context - Ohraničený kontext je explicitní hranice, ve které je doménový model platný. Každý bounded context má svůj vlastní Ubiquitous Language a model.
- Context Map - Mapa kontextů zobrazuje vztahy mezi různými bounded contexts. Tyto vztahy mohou být různého typu, například Partnership, Customer-Supplier, Conformist, Anti-Corruption Layer, atd.
- Shared Kernel - Sdílené jádro je část modelu, která je sdílena mezi dvěma nebo více bounded contexts. Toto sdílení vyžaduje úzkou spolupráci mezi týmy.
- Customer-Supplier - Vztah zákazník-dodavatel mezi dvěma bounded contexts, kde jeden kontext (dodavatel) poskytuje služby druhému kontextu (zákazník).
- Conformist - Vztah, kde jeden kontext přijímá model jiného kontextu bez možnosti jej ovlivnit.
- Anti-Corruption Layer - Vrstva, která překládá mezi dvěma bounded contexts s různými modely, aby chránila integritu cílového modelu.
- Open Host Service - Služba, která definuje protokol pro přístup k bounded contextu, aby usnadnila integraci s mnoha jinými kontexty.
- Published Language - Dobře dokumentovaný jazyk, který usnadňuje komunikaci mezi různými bounded contexts.
Taktický design (Tactical Design)
Taktický design se zabývá implementací doménového modelu v rámci jednoho bounded contextu. Klíčové vzory taktického designu zahrnují:
- Entity - Objekty, které mají identitu a kontinuitu v čase. Entity jsou definovány svou identitou, nikoli svými atributy. Například, osoba je entita, protože má svou identitu (jméno, datum narození), i když se její atributy (výska, váha) mění.
- Value Object - Hodnotové objekty jsou definovány svými atributy, nikoli identitou. Jsou neměnné (immutable) a používají se k popisu aspektů domény. Například, adresa nebo peněžní částka jsou hodnotové objekty.
- Aggregate - Agregát je shluk objektů, které jsou považovány za jednu jednotku z hlediska změn dat. Každý agregát má kořenovou entitu (Aggregate Root), která je jediným vstupním bodem pro manipulaci s agregátem.
- Domain Event - Doménová událost reprezentuje něco, co se stalo v doméně a má význam pro doménové experty. Doménové události jsou často používány pro komunikaci mezi různými bounded contexts.
- Service - Doménová služba implementuje doménovou logiku, která nepatří přirozeně do žádné entity nebo hodnotového objektu. Služby jsou bezstavové a jejich názvy by měly být odvozeny z Ubiquitous Language.
- Repository - Repozitář zapouzdřuje logiku pro přístup k persistenci agregátů. Poskytuje abstrakci nad datovým úložištěm a umožňuje pracovat s agregáty jako s objekty v paměti.
- Factory - Továrna zapouzdřuje logiku pro vytváření složitých objektů a agregátů. Používá se, když je vytvoření objektu složité nebo když je potřeba zajistit konzistenci nově vytvořených objektů.
Příklad: Agregát v e-commerce doméně
V e-commerce doméně by objednávka (Order) mohla být agregátem s následujícími částmi:
- Order - Kořenová entita (Aggregate Root)
- OrderLine - Entity reprezentující položky objednávky
- Money - Hodnotový objekt reprezentující peněžní částku
- Address - Hodnotový objekt reprezentující dodací adresu
Přístup k OrderLine entitám je možný pouze přes Order entitu, což zajistí konzistenci celého agregátu.
Implementace DDD v praxi
Implementace Domain-Driven Design v praxi zahrnuje několik klíčových kroků:
- Pochopení domény - Prvním krokem je důkladné pochopení domény ve spolupráci s doménovými experty. Tato fáze zahrnuje rozhovory, workshopy a modelování.
- Vytvoření Ubiquitous Language - Definování společného jazyka, který bude používán vývojáři i doménovými experty. Tento jazyk by měl být dokumentován a neustále aktualizován.
- Identifikace Bounded Contexts - Rozdělení složité domény do menších, jasně definovaných kontextů s explicitními hranicemi.
- Vytvoření Context Map - Definování vztahů mezi různými bounded contexts a způsobu jejich integrace.
- Modelování domény - Vytvoření doménového modelu pro každý bounded context, který zachycuje klíčové koncepty a vztahy v doméně.
- Implementace taktických vzorů - Použití taktických vzorů DDD (Entity, Value Object, Aggregate, Repository, atd.) pro implementaci doménového modelu v kódu.
- Testování - Důkladné testování doménového modelu a jeho chování, aby bylo zajištěno, že správně modeluje doménu.
- Iterace a vylepšování - Neustálé vylepšování modelu na základě zpětné vazby od doménových expertů a zkušeností z implementace.
Výhody používání DDD
Domain-Driven Design přináší mnoho výhod pro vývoj softwaru:
- Lepší komunikace - DDD usnadňuje komunikaci mezi vývojáři a doménovými experty díky společnému jazyku (Ubiquitous Language).
- Lepší pochopení domény - DDD pomáhá vývojářům lépe pochopit doménu, což vede k lepším řešením a menšímu počtu chyb.
- Flexibilita - DDD vytváří flexibilní architekturu, která se může snadno přizpůsobit změnám v doméně, což je klíčové v dnešním rychle se měnícím prostředí.
- Modularita - DDD podporuje modularitu prostřednictvím bounded contexts, což usnadňuje údržbu, rozšiřování a škálování aplikace.
- Testovatelnost - DDD vytváří kód, který je snadno testovatelný, což vede k robustnějšímu a spolehlivějšímu softwaru.
- Zaměření na hodnotu - DDD se zaměřuje na poskytování hodnoty pro podnikání tím, že se soustředí na klíčové části domény.
- Lepší spolupráce - DDD podporuje spolupráci mezi různými zúčastněnými stranami (vývojáři, doménoví experti, manažeři) díky společnému jazyku a modelu.
- Snížení technického dluhu - DDD pomáhá snižovat technický dluh tím, že podporuje jasný a srozumitelný kód, který odráží doménu.
Příklad: Ubiquitous Language v e-commerce doméně
V e-commerce doméně by Ubiquitous Language mohl zahrnovat pojmy jako:
- Košík (Cart) - Dočasná kolekce produktů, které si zákazník vybral k nákupu.
- Objednávka (Order) - Potvrzený nákup zákazníka, který obsahuje produkty, dodací adresu a platební informace.
- Katalog (Catalog) - Kolekce všech produktů dostupných k prodeji.
- Zákazník (Customer) - Osoba, která nakupuje produkty.
Tyto pojmy by byly používány konzistentně v kódu, dokumentaci a komunikaci mezi vývojáři a doménovými experty.
Výzvy a omezení DDD
I když DDD přináší mnoho výhod, má také své výzvy a omezení, které je třeba zvážit před jeho adopcí:
- Složitost - DDD může být složité pochopit a implementovat, zejména pro začátečníky. Vyžaduje hluboké pochopení domény a architektonických principů.
- Časová náročnost - Implementace DDD může být časově náročná, zejména v počátečních fázích projektu. Modelování domény a vytváření Ubiquitous Language vyžaduje čas a úsilí.
- Nevhodnost pro jednoduché aplikace - DDD je navržen pro složité aplikace s bohatou doménou. Pro jednoduché aplikace s minimální doménovou logikou může být zbytečně složitý a nákladný.
- Potřeba doménových expertů - DDD vyžaduje přístup k doménovým expertům, což nemusí být vždy možné. Bez doménových expertů je obtížné vytvořit přesný model domény.
- Organizace týmu - DDD může vyžadovat změny v organizaci týmu, aby podporovala spolupráci mezi vývojáři a doménovými experty. To může být v některých organizacích obtížné.
- Integrace s legacy systémy - Integrace DDD s existujícími legacy systémy může být náročná a může vyžadovat vytvoření Anti-Corruption Layer.
- Výkonnost - Některé vzory DDD, jako jsou agregáty a repozitáře, mohou mít dopad na výkonnost, pokud nejsou správně implementovány.
- Učebí křivka - DDD má strmou učebí křivku a může trvat nějakou dobu, než tým získá potřebné znalosti a zkušenosti.
DDD vs. jiné přístupy
Domain-Driven Design lze porovnat s jinými přístupy k vývoji softwaru:
- DDD vs. Transaction Script - Transaction Script je jednodušší přístup, který organizuje logiku kolem transakcí nebo případů užití. Je vhodný pro jednodušší aplikace, zatímco DDD je vhodnější pro složitější domény.
- DDD vs. CRUD - CRUD (Create, Read, Update, Delete) je jednoduchý přístup zaměřený na základní operace s daty. DDD jde dále a zaměřuje se na modelování domény a její chování.
- DDD vs. Hexagonální architektura - Hexagonální architektura (Ports and Adapters) se zaměřuje na oddělení domény od infrastruktury. DDD a hexagonální architektura se často kombinují, kde DDD poskytuje přístup k modelování domény a hexagonální architektura poskytuje strukturu pro oddělení domény od infrastruktury.
- DDD vs. Mikroservisy - Mikroservisy jsou architektonický styl, který rozděluje aplikaci do malých, nezávislých služeb. DDD a mikroservisy se často kombinují, kde bounded contexts z DDD mohou být implementovány jako mikroservisy.
Kdy nepoužívat DDD
DDD nemusí být vhodný pro všechny projekty. Nepoužívejte DDD, pokud:
- Vyvíjíte jednoduchou aplikaci s minimální doménovou logikou.
- Nemáte přístup k doménovým expertům.
- Váš tým nemá zkušenosti s DDD a nemá čas se ho naučit.
- Máte velmi omezený čas a rozpočet.
Shrnutí
Domain-Driven Design je mocný přístup k vývoji softwaru, který se zaměřuje na modelování domény a její implementaci v kódu. Klíčové koncepty DDD zahrnují:
- Strategický design - Bounded Contexts, Context Map, Ubiquitous Language
- Taktický design - Entity, Value Objects, Aggregates, Repositories, Domain Events, Services
- Implementační vzory - Factories, Anti-Corruption Layer, Specification, Event Sourcing
DDD je vhodný pro složité aplikace s bohatou doménou, kde je důležité přesně modelovat doménu a její chování. Přináší mnoho výhod, jako je lepší komunikace, flexibilita a modularita, ale má také své výzvy a omezení, které je třeba zvážit před jeho adopcí.
Další četba
Pro další studium Domain-Driven Design doporučujeme následující zdroje:
- Domain Language - Oficiální stránky Erica Evanse
- Domain-Driven Design: Tackling Complexity in the Heart of Software - Eric Evans
- Implementing Domain-Driven Design - Vaughn Vernon
- Domain-Driven Design Distilled - Vaughn Vernon
- DDD Community
V další kapitole se podíváme na rozdíl mezi vertikální slice architekturou a tradičním přístupem k DDD.