Domain-Driven Design (DDD)
Kod który mówi językiem biznesu. DDD to podejście które stawia domenę w centrum — Bounded Contexts, Aggregates i Event Storming prowadzą do systemów które eksperci rozumieją.
6 kluczowych konceptów DDD
DDD dzieli się na Strategic (jak podzielić system) i Tactical (jak modelować wewnątrz obszaru) — oba poziomy są kluczowe.
Ubiquitous Language
StrategicWspólny język developerów i ekspertów domenowych — te same terminy w kodzie i rozmowie
Order, OrderLine, Customer, Fulfillment — nie Record, Row, User
Bounded Context
StrategicGranica w której model domenowy jest spójny. Te same słowa mogą znaczyć coś innego w różnych contextach.
Customer w Sales vs. Customer w Shipping vs. Customer w Support
Aggregate
TacticalKlaster Entities z Aggregate Root. Jednostka transakcji i spójności. Dostęp tylko przez Root.
Order (root) + OrderItems. Nie możesz zmienić OrderItem poza Order.
Entity
TacticalObiekt z unikalną tożsamością. Tożsamość persystuje przez czas niezależnie od atrybutów.
Customer z ID 123 to wciąż ten sam Customer po zmianie adresu
Value Object
TacticalNiemutowalny obiekt bez tożsamości — definiowany przez wartości. Dwa VO z tymi samymi wartościami są identyczne.
Money(100, PLN), Address, EmailAddress, DateRange
Domain Event
TacticalNiemutowalny fakt z przeszłości. Propaguje zmiany między Bounded Contexts asynchronicznie.
OrderPlaced, PaymentFailed, ItemShipped, UserRegistered
Wzorce Context Map — relacje między Bounded Contexts
Context Map to diagram relacji między Bounded Contexts — każda relacja ma implikacje dla teamów i integracji.
Anticorruption Layer
Downstream tłumaczy model upstream na własny. Chroni własną domenę przed obcymi konceptami.
Kiedy: Gdy integracja z legacy lub zewnętrznym systemem
Shared Kernel
Dwa contexty współdzielą część modelu. Wymaga ścisłej koordynacji między teamami.
Kiedy: Blisko powiązane contexty z jednym teamem
Customer-Supplier
Upstream dostarcza dane Downstream. Upstream ma priorytet, downstream negocjuje potrzeby.
Kiedy: Hierarchia serwisów z jasnym upstream
Conformist
Downstream w pełni dostosowuje się do upstream bez negocjacji — brak wpływu.
Kiedy: Zewnętrzny API, legacy system bez możliwości zmiany
Często zadawane pytania
Co to jest Domain-Driven Design (DDD) i jakie są jego główne koncepty?
Domain-Driven Design (DDD) to podejście do projektowania oprogramowania które stawia domenę biznesową (problem który rozwiązujemy) w centrum projektu. Wprowadzone przez Erica Evansa w książce z 2003 roku. Fundamentalna idea: kod powinien odzwierciedlać język i koncepty domeny biznesowej — nie odwrotnie. Trzy poziomy DDD: Strategic DDD — jak podzielić duży system na mniejsze, spójne obszary (Bounded Contexts). Tactical DDD — wzorce projektowe wewnątrz każdego obszaru (Entities, Aggregates, Value Objects). Collaborative Modeling — Event Storming, Domain Storytelling — jak odkrywać domenę razem z ekspertami. Kluczowe koncepty: Ubiquitous Language: wspólny, precyzyjny język używany przez developerów i ekspertów domenowych. Ten sam termin znaczy to samo w kodzie i rozmowie. Bounded Context: granica modelu domenowego — w różnych contextach te same słowa mogą znaczyć coś innego ('Customer' w Sales vs. 'Customer' w Support). Domain Expert: osoba która rozumie biznes — developerzy muszą z nimi ściśle współpracować. Core Domain: obszar który daje konkurencyjną przewagę — tu inwestujesz najbardziej. Supporting Domain: wspomaga Core, ważny ale nie kluczowy. Generic Domain: nie daje przewagi — użyj gotowego produktu (auth, billing). Kiedy DDD: złożona domena biznesowa z bogatą logiką. Długoterminowy projekt. Bliski kontakt z ekspertami domenowymi. Nie warto przy prostych CRUD aplikacjach.
Bounded Context i Context Map — jak dzielić system na subdomeny?
Bounded Context to centralny pattern w Strategic DDD. Definiuje granicę w której model domenowy jest spójny i ma jedno znaczenie. Przykład e-commerce: Bounded Context 'Sales' — Customer to ktoś kto kupuje, ma historię zamówień. Bounded Context 'Shipping' — Customer to adres dostawy. Bounded Context 'Support' — Customer to przypadek problemu, ticket. Ten sam rzeczywisty customer — trzy różne modele w trzech contextach. Context Map: diagram pokazujący relacje między Bounded Contexts. Wzorce relacji: Shared Kernel: dwa contexty współdzielą część modelu. Zmiana wymaga współpracy obu teamów. Customer-Supplier: upstream context (supplier) dostarcza dane downstream (customer). Upstream ma moc, downstream dostosowuje się. Conformist: downstream podejmuje się dostosować w pełni do upstream bez negocjacji. Anticorruption Layer (ACL): downstream tłumaczy model upstream na własny. Chroni własny model przed wpływem obcych konceptów. Published Language: upstream publikuje stabilny, dobrze zdefiniowany format wymiany danych. Open Host Service: upstream udostępnia API dla wielu klientów. Separate Ways: contexty są niezależne — bez integracji. Strategic DDD i mikroserwisy: idealnym przypadkiem jest jeden mikroserwis = jeden Bounded Context. Ale nie wymuszaj tego przy małych lub niejasnych domenach. Event Storming: technika odkrywania domeny przez mapowanie domain events. Post-it notes dla events (pomarańczowe), commands (niebieskie), actors (żółte), aggregate (żółte).
Agregaty, Entities i Value Objects — taktyczny DDD?
Tactical DDD wzorce: Entity: obiekt z unikalną tożsamością (ID). Tożsamość persystuje przez czas — Customer z ID 123 to zawsze ten sam Customer nawet jeśli zmienił adres. Logika biznesowa jako metody. Value Object: obiekt bez tożsamości — definiowany przez wartości. Money (100, 'PLN') jest tym samym co każde inne Money (100, 'PLN'). Niemutowalny. Przykłady: Address, EmailAddress, Money, DateRange. Aggregate: klaster powiązanych Entities i Value Objects traktowany jako jednostka. Aggregate Root — jedyna brama do Aggregate. Wszystkie operacje przez Root. Invariants (niezmienniki) — reguły spójności które muszą być zawsze prawdziwe w granicach Aggregate. Przykład: Order jest Aggregate. OrderItems są w środku. OrderItem nie może istnieć bez Order. Nie odwołuj się bezpośrednio do OrderItem z zewnątrz Order. Domain Event: fakty z przeszłości — 'OrderPlaced', 'PaymentProcessed'. Niemutowalny rekord zdarzenia. Propagowany między Bounded Contexts przez Event Bus. Repository: interfejs do persystencji Aggregate. Tylko przez Repository pobierasz i zapisujesz Aggregate. Domain Service: logika biznesowa która nie pasuje do żadnej Entity. Bezstanowy. Np. MoneyTransferService (przelew między dwoma kontami). Operuje na wielu Aggregatach. Application Service: orkiestruje przypadki użycia. Wywołuje Repository, Domain Services. Nie zawiera logiki domenowej — tylko koordynacja. Factory: tworzenie złożonych Aggregatów.
Event Storming — jak modelować domenę z ekspertami?
Event Storming to collaborative technika modelowania domeny przez odkrywanie Domain Events. Stworzona przez Alberto Brandolini. Dlaczego Event Storming: programiści i eksperci domenowi często mówią różnymi językami. ES wymusza wspólną rozmowę. Odkrywa niewiedzę i sprzeczności w rozumieniu domeny. Trzy warianty: Big Picture Event Storming: eksploracja całej organizacji. Kto są aktorzy, co się dzieje, jakie eventy są kluczowe. Process Modeling: konkretny proces end-to-end. Software Design: projektowanie konkretnego kawałka systemu. Materiały: duże płótno (papier na rolce lub duży ekran). Post-it notes różnych kolorów. Domain Events (pomarańczowe): co się wydarzyło — imperatyw w przeszłości ('OrderPlaced', 'PaymentFailed', 'ItemShipped'). Commands (niebieskie): co triggeruje event ('PlaceOrder', 'ProcessPayment'). Actor (żółty): kto wysyła command. Policy (fioletowy): 'Gdy X to Y' — automatyczna reakcja. External System (różowy): zewnętrzne systemy. Aggregate (żółty, duży): co group eventy i commands. Hotspot (czerwony): miejsca niejasności lub kontrowersji — do dalszego zbadania. Proces: zbierz wszystkich w jednym miejscu (wszyscy mają markery i post-its). Napisz eventy bez porządku — chaos phase (20-30 min). Uszereguj eventy chronologicznie. Dodaj commands i aktorów. Odkryj Bounded Contexts przez naturalne grupowanie. Remote Event Storming: Miro, MURAL, FigJam — wirtualne płótno.
DDD i mikroserwisy — jak mapować koncepty na architekturę?
DDD dostarcza najlepszego zestawu narzędzi do projektowania mikroserwisów. Bounded Context jako mikroserwis: idealnie każdy BC to osobny serwis z własną bazą danych. Team ownership: jeden team owneruje jeden lub kilka BC/serwisów. Conway's Law: struktura organizacji odzwierciedla się w strukturze systemu. DDD pozwala świadomie projektować oba. Aggregate jako jednostka transakcji: nie ma distributed transactions między Aggregatami. Jeśli dwa Aggregaty muszą być spójne — albo to jeden Aggregate (zbyt duży?) albo eventual consistency przez events. Domain Events jako integracja: BC komunikują się przez Domain Events. Publish Integration Event gdy stan Aggregate się zmieni. Consume Integration Events od innych BC. Anticorruption Layer w każdym BC: tłumacz eventy z innych BC na własny model. Nie używaj bezpośrednio zewnętrznych modeli. CQRS w DDD: Write Model — Aggregaty z domain logic. Read Model — zdenormalizowane projekcje (per query). Osobne Handlers dla Commands i Queries. Narzędzia wspierające DDD: Axon Framework (Java) — Aggregates, Event Store, CQRS, Saga. MediatR (.NET) — Commands, Queries, Handlers. Patterny w kodzie: domain model package (bez framework dependencies). application package (orchestration). infrastructure package (DB, messaging). Hexagonal Architecture / Ports and Adapters: domena w centrum. Infrastructure adaptery na zewnątrz — DB, HTTP, messaging. Możesz zmienić bazę danych bez zmiany domeny.
Powiązane artykuły
Skontaktuj się z nami
Porozmawiajmy o Twoim projekcie. Bezpłatna wycena w ciągu 24 godzin.
Wyślij zapytanie
Telefon
+48 790 814 814
Pon-Pt: 9:00 - 18:00
adam@fotz.pl
Odpowiadamy w ciągu 24h
Adres
Plac Wolności 16
61-739 Poznań
Godziny pracy
Wolisz porozmawiać?
Zadzwoń teraz i porozmawiaj z naszym specjalistą o Twoim projekcie.
Zadzwoń teraz