Domain-driven design z pomocą AI
Pół roku w projekcie i „Order” oznacza trzy różne rzeczy w bazie kodu: wiersz w orders, DTO w usłudze checkout i view-model w Reakcie. AI wciąż wymyśla pola, których nie ma na prawdziwej encji, każda refaktoryzacja po cichu wprowadza z powrotem kwestie persystencji do warstwy domeny, a termin, którego twoi eksperci domenowi używają na spotkaniach, nie pojawia się nigdzie w kodzie. Model i język się rozjechały.
Domain-Driven Design naprawia ten rozjazd, kotwicząc kod we wspólnym słownictwie — języku wszechobecnym (Ubiquitous Language). Haczyk w tym, że DDD wymaga dyscypliny, którą asystent AI ochoczo zignoruje, dopóki nie uczynisz reguł jawnymi i ich nie wyegzekwujesz. Zrobione dobrze, AI staje się kustoszem twojej wiedzy domenowej, a nie tym, co ją eroduje.
Co z tego wyniesiesz
Dział zatytułowany „Co z tego wyniesiesz”- Konfigurację pliku kontekstowego dla każdego narzędzia, tak by AI domyślnie mówiło językiem twojej domeny
- Prawdziwy obieg w obie strony: prompt → wygenerowany agregat w TypeScript → jak sprawdzasz go względem niezmiennika
- Gotowe prompty do modelowania agregatu, generowania implementacji i pilnowania granic ograniczonych kontekstów
- Tryby awarii, które pojawiają się, gdy DDD spotyka AI, i jak je wyłapać
Krok 1: Zakoduj język wszechobecny
Dział zatytułowany „Krok 1: Zakoduj język wszechobecny”Fundamentem DDD jest język wszechobecny — słownictwo wspólne dla deweloperów i ekspertów domenowych. Pojedynczym ruchem o najwyższej dźwigni w DDD z asystentem AI jest umieszczenie tego słownictwa w pliku kontekstowym, który agent czyta przy każdym żądaniu, żeby przestał zgadywać.
Treść pliku to ta sama idea w różnych narzędziach; różni się tylko nazwa pliku i lokalizacja.
Cursor czyta reguły projektu z .cursor/rules/*.mdc. Utwórz .cursor/rules/domain.mdc i ustaw go na zawsze stosowany, aby każda tura agenta w repozytorium widziała glosariusz.
Claude Code czyta CLAUDE.md z katalogu głównego projektu (i z katalogów zagnieżdżonych) przy każdej sesji. Umieść tam glosariusz albo w CLAUDE.md wewnątrz modułu domeny, by ładował się tylko wtedy, gdy pracujesz w tym kontekście.
Codex czyta AGENTS.md z katalogu głównego projektu oraz z katalogów, w których pracuje. Umieść ten sam glosariusz w AGENTS.md, aby przebiegi App, CLI i Cloud współdzieliły go.
Treść tego pliku, niezależnie od narzędzia, to faktyczny glosariusz domeny — dlatego ogrodzony blok Markdown jest tu właściwy (to treść pliku, nie prompt):
# Ubiquitous Language — Order Context
- **Order**: a customer's request to purchase products. Aggregate Root.- **LineItem**: an entry in an Order for a product + quantity. Value Object (immutable).- **OrderStatus**: state of an Order — Pending | Paid | Shipped | Delivered | Cancelled. Enum.- **Customer**: the person who placed the Order. Referenced by `CustomerId`, never embedded.
Invariants:- An Order has at most 10 unique LineItems.- Status transitions are one-way along the list above (no Shipped → Pending).- Total is derived from LineItems; never set directly.Krok 2: Zamodeluj agregat, potem sprawdź niezmiennik
Dział zatytułowany „Krok 2: Zamodeluj agregat, potem sprawdź niezmiennik”Teraz poproś AI o zaprojektowanie agregatu Order względem tego języka i od razu zweryfikuj, że egzekwuje niezmiennik, a nie tylko się kompiluje.
-
Poproś o model. Odwołaj się do języka jawnie, by AI używało twoich terminów, a nie swoich domyślnych.
-
Przeczytaj to, co wygenerowało. Poprawny
addItemodrzuca 11. odrębny produkt i przeliczatotal;LineItemnie ma setterów. Jeśli AI wystawiło publicznysetTotalalbo pozwoliło statusowi skoczyć wstecz, model przeciekł.addItem(productId: ProductId, qty: number): void {const distinct = new Set(this.items.map(i => i.productId.value));if (!distinct.has(productId.value) && distinct.size >= 10) {throw new OrderInvariantError('An order cannot exceed 10 line items');}// ...merge or push, then recompute derived total} -
Przypnij niezmiennik testem. Nie ufaj prozie — poproś o test przypadku niepowodzenia, żeby niezmiennik nie mógł później po cichu się zregresować.
Krok 3: Pilnuj ograniczonych kontekstów
Dział zatytułowany „Krok 3: Pilnuj ograniczonych kontekstów”Drugim miejscem, gdzie AI pomaga, jest bieżące zarządzanie architektoniczne — wyłapywanie, kiedy jeden ograniczony kontekst sięga do wnętrzności innego, zamiast komunikować się przez zdarzenia lub warstwę antykorupcyjną. Tu przepływ pracy rozchodzi się w zależności od narzędzia.
Użyj trybu agenta do interaktywnego przeglądu, gdy masz otwarte pliki. Skieruj go na granicę, o którą się martwisz.
Uruchom tę samą kontrolę zarządzania w trybie headless w CI, by naruszenie granicy wywalało build, a nie tylko przegląd kodu.
Wepnij to jako automation Codeksa albo przegląd na PR-ach, by kontrola uruchamiała się według harmonogramu lub względem każdej zmiany w chmurze.
Gdy to się zepsuje
Dział zatytułowany „Gdy to się zepsuje”Co dalej
Dział zatytułowany „Co dalej”- Behavior-Driven Development — zamień język wszechobecny w wykonywalne scenariusze
- Programowanie sterowane testami — dyscyplina, która przypina twoje niezmienniki
- Przepływy pracy Agile — jak model ewoluuje sprint po sprincie