
Marketplace premium kosmetyków na 9 rynkach europejskich - Shopify Plus
Klient: Baza Cosmetics
Domain-Driven Design (DDD) jest podejściem stworzonym, aby radzić sobie z najbardziej skomplikowanymi aspektami tworzenia gier, aplikacji czy narzędzi biznesowych. Skupiając się na głównych biznesowych czynnikach modelu projektu, pomaga twórcom oprogramowania zrozumieć, ulepszyć i tłumaczyć złożone scenariusze. W tym artykule, na praktycznych przykładach, pokażemy jak skutecznie wprowadzić ten proces w życie.
CEO
01 lis 2023
Domain-Driven Design, znane również jako DDD, to podejście do tworzenia oprogramowania, które koncentruje się na głębokim zrozumieniu specyfiki działalności, dla której powstaje dany system. Jego kluczowym założeniem jest stworzenie modelu dziedziny, czyli abstrakcyjnego reprezentanta biznesowej rzeczywistości, który będzie w pełni zgodny z realiami przedsiębiorstwa. Promuje silną współpracę między zespołem deweloperskim a ekspertami od strony biznesowej, co ma na celu stworzenie oprogramowania dokładnie odzwierciedlającego logikę i zasady panujące w organizacji. Istotnym elementem DDD jest również właściwe odseparowanie logiki biznesowej od pozostałych elementów systemu, co zwiększa klarowność i łatwość zarządzania projektem.

Klient: Baza Cosmetics

Klient: HR Hints
Branża: HR / HRTech

Klient: Klient (Aplikacja webowa do nauki programowania)
Branża: Edukacja / EdTech
Architektura oprogramowania ma kluczowe znaczenie dla poprawnego działania i rozwijania systemów informatycznych. Na tym polu pojawia się Domain-Driven Design, czyli projektowanie zorientowane na dziedzinę. Jest to koncepcja, której celem jest skupienie się na podstawowych problemach biznesowych oraz na modelowaniu ich w oprogramowaniu. Polega na tworzeniu jednolitego modelu dziedziny, który odzwierciedla rzeczywistość, z którą mierzy się organizacja. Priorytetem staje się zrozumienie i precyzyjne odwzorowanie procesów biznesowych, a nie technologia w jakiej ten model zostanie zaimplementowany. Dzięki stosowaniu DDD, zespół programistów zyskuje możliwość tworzenia wysoce skalowalnych i łatwo rozwijalnych rozwiązań, co znacznie zwiększa ich wartość dla biznesu.
W Domain-Driven Design, "budowanie bloków" odnosi się do fundamentalnych elementów, z których składają się modele domenowe: agregatów, encji i wartości obiektów. Encje są obiektami z unikalną tożsamością, które pozwalają na śledzenie ich przez cykl życia aplikacji, nawet jeśli ich atrybuty ulegną zmianie. Wartości obiektów, w przeciwieństwie do encji, definiowane są przez ich atrybuty i nie posiadają własnej tożsamości. Agregaty zaś grupują jeden lub więcej obiektów domenowych (encje i wartości obiektów) w większe całości, określając granice i zasady ich współpracy. Każdy agregat posiada korzeń agregatu, który jest encją służącą jako punkt wejścia do agregatu i gwarantuje spójność całej grupy. Przyjęcie tych konceptów pozwala na tworzenie bardziej zorganizowanych, spójnych i łatwych w utrzymaniu modeli domenowych, które są lepiej zrozumiałe dla wszystkich członków zespołu projektowego.

Kluczowe elementy DDD to: model domeny, stworzony w taki sposób, aby odzwierciedlać realia biznesowe; Bounded Context, odpowiadający za wydzielenie konkretnych obszarów systemu; i Ubiquitous Language, służący do tworzenia jednolitego języka technicznego i biznesowego. Dodatkowo, w DDD ważne są również takie zasady jak: Layered Architecture, czyli podział systemu na warstwy, i Continuous Integration, zasada umożliwiająca ciągłą integrację zmian w projekcie. Stosowanie Domain-Driven Design ma na celu ułatwienie zrozumienia systemu oraz poprawę komunikacji pomiędzy członkami zespołu.
Język Ubiquitous Language (wszechobecny język) to kluczowy element Domain-Driven Design, który ma na celu zniwelowanie bariery komunikacyjnej między zespołem deweloperskim a ekspertami domenowymi. Jest to wspólny, jednoznacznie zdefiniowany zestaw terminów, które opisują pojęcia, procesy i reguły obowiązujące w danej domenie biznesowej. Dzięki temu wszyscy członkowie projektu – programiści, analitycy, menedżerowie oraz klienci – używają tego samego słownictwa, eliminując nieporozumienia i zwiększając spójność modelu domenowego. Ubiquitous Language powinien być stosowany zarówno w dokumentacji, rozmowach zespołowych, jak i bezpośrednio w kodzie źródłowym (np. nazewnictwo klas, metod czy modułów). To podejście pomaga tworzyć bardziej czytelne, łatwe w utrzymaniu i zgodne z rzeczywistością rozwiązania, co znacząco wpływa na jakość projektowanego systemu.
Język ograniczonego kontekstu (Bounded Context) jest kluczowym pojęciem w Domain-Driven Design, podkreślającym znaczenie jasnych granic w obrębie których określone modele domenowe są ważne i stosowane. Definiuje on środowisko, w którym specyficzne dla domeny terminy i modele mają jednoznaczne znaczenie, eliminując niejednoznaczności i upraszczając komunikację w zespole. Bounded Context wspiera podział większego systemu na mniejsze, zarządzalne części, co pozwala zespołom pracować nad poszczególnymi segmentami domeny niezależnie, redukując złożoność i ryzyko błędów. W kontekście architektury mikrousług, każda usługa często odpowiada jednemu Bounded Context, co sprzyja modularności i skalowalności systemu.
Integracja Domain-Driven Design z architekturą mikrousług oferuje potężny sposób na zarządzanie złożonością systemów i promowanie ich skalowalności. W takim podejściu, mikrousługi są projektowane wokół określonych domen biznesowych lub Bounded Contexts, co zapewnia silną spójność wewnętrzną i luźne powiązania między usługami. Dzięki temu, każda mikrousługa może być rozwijana, wdrażana i skalowana niezależnie od innych, co ułatwia zarządzanie cyklem życia aplikacji i pozwala na szybsze reagowanie na zmieniające się wymagania biznesowe. DDD dostarcza narzędzi i technik do tworzenia precyzyjnych modeli domenowych, które są następnie implementowane jako niezależne mikrousługi. Takie podejście nie tylko zwiększa modularność i elastyczność systemu, ale także ułatwia integrację nowych usług, zachowując przy tym spójność biznesową i techniczną na poziomie całego przedsięwzięcia.

Jest to podejście do tworzenia oprogramowania, które stawia na pierwszym miejscu dogłębne zrozumienie biznesu, a następnie przekłada je na strukturę kodu. Efektywne zastosowanie DDD przyczynia się do sprawniejszej komunikacji między programistami, a również doskonale integruje się z praktykami Agile i DevOps. W praktyce, pozwala na budowanie aplikacji, które są łatwiejsze do testowania, rozbudowy i utrzymania, gdyż są one silnie sprzężone z regułami i procesami biznesowymi. To sprawia, że w przypadku zmian w biznesie, zwykle wystarczy jedynie niewielka modyfikacja kodu. Korzystając z DDD, tworzymy oprogramowanie bardziej zgodne z rzeczywistymi potrzebami biznesu, co przekłada się na wyższe zadowolenie klientów oraz ogólną efektywność przedsiębiorstwa.
Domain-Driven Design jest potężnym narzędziem, które może przekształcić sposób, w jaki organizacje rozwijają i projektują swoje systemy informatyczne. Niemniej jednak, jak każda zaawansowana metodologia, ma swoje wyzwania i pułapki, które mogą stanąć na drodze do sukcesu. Jednym z głównych wyzwań jest zapewnienie, aby cały zespół deweloperski posiadał głębokie zrozumienie domeny biznesowej – bez tego modele domenowe mogą okazać się nietrafione lub zbyt skomplikowane. Ponadto, DDD wymaga ścisłej współpracy między ekspertami domenowymi a zespołem technicznym, co w praktyce może być trudne do osiągnięcia ze względu na różnice w języku biznesowym i technicznym. Inną pułapką jest nadmierne skomplikowanie modeli, co może prowadzić do zbyt długiego czasu wdrożenia i utrudniać elastyczność w obliczu zmieniających się wymagań biznesowych.
Domain-Driven Design ma reputację metodologii dla "dużych projektów", co często odstrasza startupy. To nieporozumienie — DDD opiera się na zestawie zasad, które można stopniowo wprowadzać niezależnie od skali projektu. Pytanie nie brzmi "czy DDD" ale "który poziom DDD".
W startupie (faza MVP): wystarczają trzy elementy DDD — wspólny słownik (Ubiquitous Language), wyraźne nazwy klas/modułów odpowiadające biznesowi, oraz separacja logiki domenowej od warstwy infrastruktury. Nie ma sensu wdrażać CQRS, Event Sourcing czy bounded contexts gdy zespół ma 3 deweloperów i jeden moduł.
W przedsięwzięciu enterprise: pełen DDD okazuje się niezbędny gdy domena ma 10+ bounded contexts, zespoły są podzielone funkcjonalnie, a integracje z systemami legacy wymagają jasnych granic. Wówczas profesjonalne wdrożenia custom developmentu typowo zaczynają się od event stormingu — warsztatu, który mapuje całą domenę przed napisaniem pierwszej linijki kodu.
Punkt przełomu: z naszej praktyki wynika, że pełen DDD opłaca się od ~50k linii kodu lub gdy projekt ma działać 5+ lat. Poniżej tego progu wystarczy "lekki DDD" (Ubiquitous Language + clean architecture).
Z naszego doświadczenia w realizacji projektów custom developmentu, wdrożenia DDD najczęściej zawodzą z czterech powodów — żaden z nich nie jest techniczny.
1. Brak Domain Expert dostępnego dla zespołu. DDD wymaga ciągłej rozmowy między programistami a osobą znającą biznes. Jeśli dostęp do eksperta jest ograniczony do "1 godzina spotkania w tygodniu", powstaje model domeny oparty na domysłach. Rozwiązanie: zaplanować Domain Expert jako stakeholdera projektu, nie jako "dorywczego doradcę".
2. Tłumaczenie pojęć biznesowych na angielski. Polski biznes ma własną terminologię (np. "delegacja", "faktura korygująca", "rachunek WB") — tłumaczenie ich na angielski w kodzie tworzy mismatch z dokumentacją biznesową. Trzymaj polskie nazwy w nazwach klas/metod, nawet jeśli reszta kodu jest po angielsku.
3. Over-engineering early. Wprowadzanie Aggregates, Value Objects, Domain Events od pierwszego sprintu spowalnia development bez korzyści. Zaczynaj prosto, dodawaj złożoność gdy domena to wymusza.
4. Brak refactoringu modelu domeny. Model domeny powinien ewoluować razem z biznesem. Zespoły, które boją się refactoringu modelu, kończą z modelem niereagującym na zmiany rynku.
FAQ
Domain-Driven Design to podejście do tworzenia oprogramowania, w którym kod jest bezpośrednio modelowany według logiki i pojęć z dziedziny biznesowej, a nie wokół technologii. Kluczowym założeniem jest zbudowanie tzw. modelu domeny — abstrakcyjnego odwzorowania realiów organizacji — przy ścisłej współpracy programistów z ekspertami biznesowymi. DDD wymusza także separację logiki domenowej od warstwy infrastruktury, co zwiększa czytelność, testowalność i odporność systemu na zmiany wymagań.
Najważniejsze klocki budowlane to: Encje (obiekty z unikalną tożsamością śledzoną przez cykl życia), Value Objects (definiowane przez atrybuty, bez tożsamości), Agregaty (grupy obiektów z korzeniem agregatu jako jedynym punktem wejścia), Ubiquitous Language (jednolity słownik biznesowo-techniczny) oraz Bounded Context (granice, w których konkretny model domeny obowiązuje). Do tego dochodzi Layered Architecture i ciągła integracja jako zasady wspierające. Ich łączne zastosowanie tworzy modułowy, zrozumiały system.
Ubiquitous Language to wspólny, jednoznacznie zdefiniowany słownik terminów używany przez wszystkich uczestników projektu — programistów, analityków, menedżerów i klientów. Te same nazwy pojęć biznesowych pojawiają się w rozmowach, dokumentacji oraz wprost w kodzie (klasy, metody, moduły). Eliminuje to barierę „biznes mówi A, programista pisze B”, redukując nieporozumienia i sprawiając, że kod sam w sobie staje się czytelną dokumentacją domeny. To jeden z najprostszych do wdrożenia, a najmocniej działających elementów DDD.
Naturalne dopasowanie: każda mikrousługa najczęściej odpowiada jednemu Bounded Contextowi. Dzięki temu usługi mają silną spójność wewnętrzną (jeden, jasno zdefiniowany model domeny) i luźne powiązania między sobą — komunikują się przez kontrakty, nie przez współdzielony schemat bazy. Pozwala to zespołom rozwijać, wdrażać i skalować poszczególne usługi niezależnie. DDD dostarcza technik (event storming, context mapping), które pomagają poprawnie wyznaczyć granice mikrousług — bez tego mikrousługi często rodzą się zbyt drobne lub zbyt powiązane ze sobą.
DDD opiera się na zestawie zasad, które można wdrażać stopniowo. W startupie (faza MVP) wystarczają trzy elementy: Ubiquitous Language, nazwy klas i modułów odpowiadające biznesowi oraz separacja logiki domeny od infrastruktury — bez CQRS, Event Sourcing czy formalnych bounded contexts. Pełen DDD opłaca się od ~50 tysięcy linii kodu lub gdy projekt ma działać 5+ lat. W enterprise pełne wdrożenie (z event stormingiem na starcie) jest niezbędne, gdy domena obejmuje 10+ bounded contexts i wymaga integracji z systemami legacy.
Cztery najczęstsze, wszystkie nietechniczne: brak Domain Experta dostępnego dla zespołu na co dzień (model oparty na domysłach), tłumaczenie polskich pojęć biznesowych na angielski w kodzie (mismatch z dokumentacją biznesową), over-engineering od pierwszego sprintu (Aggregates/Value Objects bez potrzeby) oraz brak refactoringu modelu wraz z ewolucją biznesu. Wszystkie powodują, że DDD traci swoją zasadniczą wartość — bliską zgodność kodu z realiami organizacji.
Blog
W ostatnim czasie coraz więcej firm decyduje się na wykorzystanie technologii Headless CMS. Jest to spowodowane coraz większym zapotrzebowaniem na elastyczność i możliwość tworzenia aplikacji internetowych, które będą dostosowane do indywidualnych potrzeb użytkownika.
HTTP 301 to status kodu, który informuje przeglądarkę oraz wyszukiwarki, że zasób, którego dotyczy żądanie, został przeniesiony na stałe do nowego adresu URL. Oznacza to, że zasób już nie jest dostępny pod starym adresem URL, a wszystkie przyszłe żądania powinny kierować do nowego adresu.
Joomla to popularny system zarządzania treścią (CMS), który pozwala na łatwe tworzenie i zarządzanie witrynami internetowymi. Jest to otwarty i darmowy system, który jest dostępny dla każdego, kto chce stworzyć profesjonalną stronę internetową.
Metody tablicowe w JavaScript to specjalne funkcje, które pozwalają na wykonywanie różnych operacji na tablicach danych. Dzięki nim możemy m.in. sortować, filtrować.
Błąd HTTP 401 to komunikat o błędzie, który oznacza, że użytkownik nie ma dostępu do zasobu, o który prosił. Ten błąd jest zwykle spowodowany brakiem autoryzacji lub brakiem uprawnień do dostępu do zasobu.
Ciąg Fibonacciego to ciąg liczb naturalnych, który zaczyna się od 0 i 1, a każda kolejna liczba jest sumą dwóch poprzednich. Ciąg ten został opisany przez włoskiego matematyka Leonardo Fibonacciego w XII wieku.