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:

  1. Zaměření na doménu - DDD se zaměřuje na doménu a doménovou logiku. Technické detaily jsou sekundární.
  2. 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.
  3. Bounded Context - DDD rozděluje složité domény do menších, jasně definovaných kontextů s explicitními hranicemi.
  4. Model-Driven Design - DDD používá model jako základ pro návrh softwaru. Model je zjednodušenou reprezentací domény.
  5. Strategic Design - DDD poskytuje nástroje pro strategický návrh, který pomáhá definovat hranice mezi různými částmi systému.
  6. 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.

Entity identity mutableState equals(other) bool ValueObject immutableState noIdentity equals(other) bool AggregateRoot Entity rootOfConsistencyBoundary transactionalConsistency Repository find(id) save(aggregate) remove(aggregate) DomainService stateless businessLogic() operatesOnMultipleEntities() Factory createComplexObjects() encapsulatesCreationLogic() DomainEvent name timestamp data notification BoundedContext autonomousDomain explicitBoundaries ubiquitousLanguage je obsahuje obsahuje pracuje s vytváří používá používá publikuje obsahuje obsahuje obsahuje

Implementace DDD v praxi

Implementace Domain-Driven Design v praxi zahrnuje několik klíčových kroků:

  1. 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í.
  2. 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.
  3. Identifikace Bounded Contexts - Rozdělení složité domény do menších, jasně definovaných kontextů s explicitními hranicemi.
  4. Vytvoření Context Map - Definování vztahů mezi různými bounded contexts a způsobu jejich integrace.
  5. 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ě.
  6. 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.
  7. 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.
  8. 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.

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:

V další kapitole se podíváme na rozdíl mezi vertikální slice architekturou a tradičním přístupem k DDD.