Domain-Driven Design (DDD) – co to jest i kiedy ma sens
Wyobraź sobie system, który działa – technicznie. Testy przechodzą, kod się kompiluje, serwery nie płoną. A jednak każda nowa funkcjonalność to tygodnie walki z kodem, a rozmowa z biznesem kończy się wzajemnym niezrozumieniem. Znasz to? Domain-Driven Design (DDD) to podejście, które próbuje rozwiązać dokładnie ten problem – i nie, nie chodzi tylko o nową warstwę abstrakcji.
DDD to filozofia projektowania oprogramowania, w której centrum stawia się domenę biznesową – a nie technologię, bazę danych czy framework. Zaproponowane przez Erica Evansa w książce z 2003 roku podejście przeżywa dziś renesans, głównie za sprawą mikroserwisów, złożonych systemów enterprise i rosnącej potrzeby bliskiej współpracy między developerami a ekspertami domenowymi. Sprawdźmy, na czym DDD polega i – co równie ważne – kiedy naprawdę ma sens jego wdrożenie.
Spis treści
DDD – co to jest? Więcej niż wzorzec projektowy
Domain-Driven Design to zestaw praktyk, wzorców i zasad służących projektowaniu złożonego oprogramowania w taki sposób, by kod odzwierciedlał rzeczywistość biznesową. Kluczowe słowo to „domena” – czyli obszar, dla którego budujemy system. Domeną mogą być: ubezpieczenia, e-commerce, logistyka, bankowość czy platforma rekrutacyjna.
Evans zaproponował, by developerzy i eksperci biznesowi mówili tym samym językiem – dosłownie. Nie „obiekt klasy UserOrderProcessingHandler”, ale „zamówienie”, „klient”, „faktura”. To podejście Evans nazwał Ubiquitous Language (językiem wszechobecnym) – jednym słownictwem, które obowiązuje zarówno w rozmowach z biznesem, jak i w kodzie, dokumentacji i testach.
DDD dzieli się na dwa poziomy: strategiczny i taktyczny. Poziom strategiczny odpowiada na pytanie „jak podzielić system?”, a taktyczny – „jak zbudować każdy z kawałków?”. Oba są ważne, ale to właśnie poziom strategiczny jest tym, o którym mówi się za rzadko.
DDD a architektura – jak to wygląda w praktyce?
DDD nie narzuca konkretnej architektury – ale naturalnie paruje się z kilkoma dobrze znanymi podejściami. Najczęściej spotkasz je razem z architekturą heksagonalną (Ports & Adapters), CQRS (Command Query Responsibility Segregation) oraz Event Sourcing. Każde z nich wzmacnia idee DDD z nieco innej strony.
W klasycznym podejściu DDD wyróżniamy kilka warstw:
- Warstwa domeny – serce systemu. Tu żyją encje (Entities), obiekty wartości (Value Objects), agregaty (Aggregates) i zdarzenia domenowe (Domain Events). Logika biznesowa należy wyłącznie tutaj.
- Warstwa aplikacji – orkiestruje przepływ. Use-case’y, serwisy aplikacyjne, obsługa komend i zapytań. Nie zawiera logiki biznesowej – deleguje ją do domeny.
- Warstwa infrastruktury – implementacje repozytoriów, klientów HTTP, kolejek, baz danych. Nie wie nic o domenie – to domena definiuje interfejsy, infrastruktura je implementuje.
- Warstwa interfejsu użytkownika – REST API, GraphQL, CLI, UI. Punkt wejścia do systemu, który wywołuje warstwę aplikacji.
Najważniejsza zasada tej architektury? Domena jest izolowana od zewnętrznych zależności. Framework może się zmienić. Baza danych może się zmienić. Logika biznesowa – powinna być od tego niezależna.
Bounded Context – najważniejsze pojęcie w DDD
Jeśli miałbyś/miałabyś zapamiętać z DDD tylko jedno pojęcie – niech to będzie Bounded Context (kontekst ograniczony). To wyraźna granica, wewnątrz której obowiązuje jeden spójny model domeny i jeden język wszechobecny.
Wyobraź sobie platformę e-commerce. Słowo „produkt” ma inne znaczenie w kontekście katalogu produktów (nazwa, zdjęcia, opis) niż w kontekście magazynu (lokalizacja, ilość, partie) czy fakturowania (cena, stawka VAT, kod PKWiU). Próba budowania jednego, globalnego modelu „Produktu” – to droga do chaosu. Bounded Context mówi: każdy kontekst ma swój model, dopasowany do swoich potrzeb.
Między kontekstami potrzebne są jasne zasady integracji. DDD opisuje je przez tzw. Context Map – mapę, która pokazuje, jak konteksty się ze sobą komunikują. Wzorce tej komunikacji to m.in.:
- Shared Kernel – dwa konteksty współdzielą część modelu (wymaga ścisłej koordynacji),
- Customer/Supplier – jeden kontekst dostarcza dane, drugi konsumuje (np. magazyn dostarcza dane do fakturowania),
- Anti-Corruption Layer (ACL) – warstwa tłumacząca modele, gdy integrujemy zewnętrzne systemy (np. legacy, SAP),
- Open Host Service / Published Language – kontekst udostępnia publiczne API z dobrze zdefiniowanym protokołem.
Bounded Context to też naturalny kandydat na granicę mikroserwisu. To dlatego DDD i mikroserwisy tak dobrze się uzupełniają – choć jedno nie wymaga drugiego.
Taktyczne wzorce DDD – słownik pojęć
Poziom taktyczny DDD dostarcza konkretnych wzorców do budowania modelu domeny. Oto te, z którymi spotkasz się najczęściej.
Entity (Encja)
Obiekt z unikalną tożsamością, która utrzymuje się w czasie. Zamówienie z id #12345 to zawsze to samo zamówienie, nawet jeśli zmieni się jego status czy wartość. Tożsamość – nie atrybuty – definiuje encję.
Value Object (Obiekt Wartości)
Obiekt bez tożsamości, definiowany wyłącznie przez swoje atrybuty. Adres „ul. Marszałkowska 1, Warszawa” jest równy innemu obiektowi z identyczną wartością. Value Objects są niezmienne (immutable) i można je bezpiecznie współdzielić. Typowe przykłady: Money, Address, Email, DateRange.
Aggregate (Agregat)
Klaster powiązanych encji i value objectów traktowany jako jedna całość. Agregat ma swój Aggregate Root – jedyny punkt wejścia do operacji na agregacie. Żaden zewnętrzny kod nie powinien modyfikować obiektów wewnątrz agregatu z pominięciem roota. Agregat gwarantuje spójność biznesową.
Domain Event (Zdarzenie Domenowe)
Fakt, który zdarzył się w domenie i ma znaczenie biznesowe. „ZamówienieZłożone”, „PłatnośćZrealizowana”, „KlientZablokowany” – zdarzenia domenowe opisują przeszłość (zawsze używamy czasu przeszłego). Są fundamentem Event-Driven Architecture i Event Sourcingu.
Repository (Repozytorium)
Abstrakcja zapewniająca dostęp do agregatów, ukrywająca szczegóły przechowywania danych. Domena definiuje interfejs repozytorium (np. OrderRepository), a infrastruktura dostarcza jego implementację (np. opartą na PostgreSQL). To odwrócenie zależności.
Domain Service (Serwis Domenowy)
Gdy logika biznesowa nie należy naturalnie do żadnej encji ani value objectu – trafia do serwisu domenowego. Np. „przeliczenie ceny zamówienia z uwzględnieniem rabatów i kampanii” może wymagać współpracy kilku agregatów i naturalnie staje się serwisem domenowym.
DDD w praktyce – przykłady z polskich firm i projektów
Teoria to jedno – zobaczmy, jak DDD wygląda w polskich realiach. W Polsce DDD stosują m.in. firmy z sektora fintech, insurtech, e-commerce i ERP, gdzie złożoność domeny biznesowej jest wysoka.
Przykład 1: System ubezpieczeń
Wyobraź sobie platformę sprzedaży ubezpieczeń. Domena jest złożona: kalkulacja składki, underwriting, obsługa szkód, rozliczenia prowizji, raportowanie KNF. Każdy z tych obszarów ma własne reguły, ekspertów i słownictwo. Podejście bez DDD – jeden monolityczny serwis InsuranceService – kończy się kodem, którego nikt nie rozumie po sześciu miesiącach. DDD pozwala wydzielić bounded contexty: Pricing, Underwriting, Claims, Commissions, Reporting – każdy z własnym modelem i regułami.
Przykład 2: Platforma e-commerce B2B
W platformie B2B „klient” to zupełnie inne pojęcie w kontekście sprzedaży (lead, kontrakt, warunki handlowe), logistyki (punkt dostawy, godziny okna czasowego) i finansów (limit kupiecki, płatności odroczone). Bez Bounded Context te modele wchodzą sobie w drogę. Z DDD każdy kontekst ma swojego klienta – i nie ma w tym nic złego.
Przykład 3: Platforma HR/rekrutacyjna
Bliskie polskiemu środowisku IT – pomyśl o systemie takim jak ATS (Applicant Tracking System). Kandydat w kontekście rekrutacji (CV, aplikacja, oceny) to inny obiekt niż pracownik w kontekście kadrowo-płacowym (umowa, PESEL, wynagrodzenie). Event domenowy KandydatZatrudniony inicjuje proces onboardingu w innym kontekście. Przepływ jest czytelny, granice jasne.
Kiedy DDD ma sens – a kiedy to przerost formy nad treścią?
To zasadnicze pytanie, które wielu developerów pomija. DDD to potężne narzędzie z konkretnym kosztem: stromą krzywą uczenia, większą ilością kodu i potrzebą bliskiej współpracy z biznesem. Warto je ponosić tylko wtedy, gdy złożoność domeny to uzasadnia.
DDD ma sens, gdy…
- Domena jest złożona i pełna reguł biznesowych, które ciągle się zmieniają,
- Biznes i IT muszą blisko współpracować – masz dostęp do ekspertów domenowych,
- System będzie rozwijany przez lata przez wiele zespołów,
- Masz trudności ze zrozumieniem istniejącego kodu przez brak mapowania na rzeczywistość biznesową.
DDD to prawdopodobnie zbyt dużo, gdy…
- Budujesz prosty CRUD – formularz do bazy danych,
- Startup w fazie MVP – czas do rynku ważniejszy niż architektura,
- Mały, jednorodny system z jednym zespołem i stabilną domeną,
- Brak rzeczywistej współpracy z biznesem – DDD bez eksperta domenowego to tylko imitacja.
Eric Evans sam przyznaje, że DDD nie sprawdza się wszędzie. W jego modelu Core Domain – czyli obszar, w którym budujesz przewagę konkurencyjną – zasługuje na pełne DDD. Generic Subdomains (np. autoryzacja, maile) możesz obsłużyć gotowymi rozwiązaniami. Supporting Subdomains – uproszczonymi podejściami. Nie musisz DDD-ować całego systemu.
Event Storming – jak odkryć domenę przed kodowaniem
Zanim napiszesz pierwszą linię kodu, warto wspólnie z biznesem odkryć domenę. Tu z pomocą przychodzi Event Storming – warsztat grupowy wymyślony przez Alberta Brandoliniego. Na dużym arkuszu papieru (lub Miro) uczestnicy – zarówno developerzy, jak i eksperci domenowi – przyklejają kolorowe karteczki reprezentujące zdarzenia domenowe, komendy, aktorów, polityki i systemy zewnętrzne.
Event Storming to szybki sposób na ujawnienie wiedzy ukrytej w głowach ekspertów, wykrycie punktów spornych (tam, gdzie ludzie się nie zgadzają – zwykle jest ukryta złożoność), naturalnych granic między kontekstami i luk w procesach biznesowych. W polskich firmach Event Storming zyskuje popularność jako narzędzie do modernizacji legacy systemów – najpierw mapujesz co jest, potem projektujesz co powinno być.
DDD w 2026 roku – AI, mikroserwisy i nowe wyzwania
DDD nie jest młodą ideą – ma ponad dwie dekady. Ale z rosnącą złożonością systemów (mikroserwisy, distributed systems) i presją na skrócenie czasu dostarczania wartości biznesowej, zasady DDD są aktualniejsze niż kiedykolwiek.
Ciekawe pytanie dotyczy AI: jak modele językowe i generatywne AI wpasowują się w DDD? Coraz więcej firm traktuje moduł AI jako odrębny Bounded Context – AI jako usługę wewnętrzną z jasno zdefiniowanym interfejsem. Logika decyzyjna pozostaje w domenie, AI dostarcza tylko wzbogacone dane (np. klasyfikację, rekomendacje). To zdrowsze podejście niż wszczepianie promptów bezpośrednio w logikę biznesową.
Warto też śledzić trend Modulith – modularnego monolitu, który stosuje granice Bounded Contextów bez podziału na osobne serwisy. To coraz popularniejsza alternatywa dla zespołów, które chcą korzyści DDD bez operacyjnej złożoności mikroserwisów. Spring Modulith czy odpowiedniki w Pythonie i Go są dowodem na to, że rynek szuka złotego środka.
Jak zacząć z DDD – praktyczne pierwsze kroki
DDD nie wymaga rewolucji z dnia na dzień. Możesz zacząć małymi krokami:
- Zbuduj słownik domeny – usiądź z biznesem i spiszcie pojęcia, które wszyscy rozumieją tak samo. To zaskakująco trudne i odkrywcze ćwiczenie.
- Zorganizuj Event Storming – nawet 2-3-godzinne Big Picture Event Storming z kluczowymi interesariuszami da więcej wglądu niż tygodnie analizy dokumentów.
- Zacznij od Core Domain – zidentyfikuj, gdzie tworzysz realną wartość biznesową i tam aplikuj DDD. Reszty na razie nie ruszaj.
- Przeczytaj „niebieską księgę” – „Domain-Driven Design” Evansa to lektura obowiązkowa. Jeśli szukasz szybszego startu – „Implementing DDD” Vaughna Vernona lub „Learning Domain-Driven Design” Vladika Khonikova to świetne uzupełnienia.
- Wejdź do społeczności – DDD Community Polska, konferencje jak DDD Europe czy lokalne meetupy to miejsca, gdzie praktycy dzielą się doświadczeniami z wdrożeń – zarówno sukcesami, jak i kosztownymi błędami.
Podsumowanie – DDD to inwestycja, nie koszt
Domain-Driven Design to nie kolejna moda architektoniczna ani zestaw wzorców do mechanicznego stosowania. To sposób myślenia o oprogramowaniu, który stawia zrozumienie domeny biznesowej ponad elegancję techniczną. Gdy złożoność systemu rośnie, a komunikacja z biznesem kuleje – DDD daje konkretne narzędzia do opanowania chaosu.
Najważniejsze wnioski, które warto zabrać ze sobą:
- DDD to filozofia i zestaw wzorców – nie framework ani biblioteka,
- Bounded Context to najważniejsze pojęcie strategiczne – naturalna granica mikroserwisu,
- DDD wymaga bliskości z biznesem – bez eksperta domenowego to tylko droga abstrakcja,
- Nie musisz stosować DDD wszędzie – skup się na Core Domain,
- Event Storming to świetny punkt startowy – niezależnie od dalszych decyzji architektonicznych.
Podobne artykuły
Scrum – kompletny przewodnik po frameworku Agile
Jira – zarządzanie projektami IT krok po kroku
Junior Developer – jak zdobyć pierwszą pracę w IT
Rekrutacja to rozmowa, nie algorytm. Jak mBank wykorzystuje AI w procesach rekrutacyjnych
Data Science – czym jest i jak wejść w tę branżę?
Kubernetes – orkiestracja kontenerów w praktyce
Docker – konteneryzacja aplikacji od podstaw