DÍL 03b KAPITOLA 03 · SEKCE 03.06–03.09, 03.11–03.12

Anti-Corruption Layer, OHS a Published Language

Role na hranici mezi kontexty: Conformist, Anti-Corruption Layer, Open Host Service a Published Language v Symfony 8. Plus jak nakreslit Context Map za 90 minut a co s Big Ball of Mud.

Přehrávač YouTube se načte až po kliknutí · otevřít na YouTube (nové okno) ↗

Přepis dílu komentář tak, jak zazní ve videu

Cizí model prosakuje do domény

Doménová třída Order má najednou pole legacyInvoiceNumber a událost OrderShipped nese stripeChargeId. Cizí model vám prostě prosákl do domény.

O tom, co do domény proteče, se rozhoduje na hranici, podle role, kterou hraje každý konec vztahu. Role jsou čtyři.

Conformist

Conformist je role downstreamu, který vědomě rezignuje na vlastní model. Od upstreamu převezme všechno tak, jak to je, bez překladu.

Evans tu situaci popisuje bez příkras. Když upstream nemá důvod vyjít vstříc, je downstream bezmocný. Převzetím cizího modelu si aspoň ušetří překlad a navíc získá společný jazyk s upstreamem.

V knize je to reporting, který čte platby ze Stripe bez jakékoli úpravy. Částka není hodnotový objekt Money a měna zůstane malými písmeny, jak ji Stripe pošle.

Platí se za to křehkostí. Každá neslučitelná změna upstreamu rozbije i vás. A přidat druhého poskytovatele, třeba PayPal, je těžké, protože celá logika kopíruje model Stripe.

Jinak je to u standardu. Kdo se přizpůsobí ISO 20022 nebo CloudEvents, mluví stejným jazykem jako celý obor. U proprietárního dodavatele ale platí, že jakmile na jeho datech stojí vaše doménová pravidla, patří mezi něj a doménu Anti-Corruption Layer.

Anti-Corruption Layer

Anti-Corruption Layer je izolační vrstva mezi vaší doménou a cizím systémem. Překládá cizí pojmy do vašich a neplatné stavy zastaví dřív, než se dostanou dovnitř.

Naivní verze vypadá takhle. Aplikační služba sama kontroluje, jestli má odpověď z legacy SOAP status PAID. Přesně tudy prosakuje cizí model, který jste viděli na začátku.

Kniha tu práci svěřuje translátoru. Je to finální třída s jedinou veřejnou metodou a bez stavu. Vstupem je DTO upstreamu, výstupem doménová událost.

Translátor má tři odpovědnosti. Schema mapping řeší, jak vypadá payload. Concept translation se stará o význam, číslo faktury z legacy se třeba u nás stane typovaným identifikátorem. A třetí, anti-corruption, se ptá, jestli se datům dá vůbec věřit.

Záporná částka, neznámý status nebo nečitelné datum skončí výjimkou. Bez té poslední kontroly by z prázdného řetězce vznikl aktuální čas a doména by se dozvěděla, že faktura je zaplacená právě teď.

Měnu translátor překládá na enum Currency a neznámou odmítne. Kdyby tam bylo natvrdo euro, tiše by se změnila částka na každé faktuře v jiné měně.

Testy pak mají tvar dvou tabulek. V jedné je vstup a výstup, ve druhé vstup a výjimka. Každý nový okrajový případ z produkce přibude jako další řádek.

Výchozí volbou ale ACL není a kniha jmenuje tři situace, kdy se nevyplatí. Obě strany mluví stejnými pojmy, takže není co překládat. Samostatná služba by přidala síťový skok a latenci. Nebo legacy za tři měsíce odchází a vrstva by se nestihla zaplatit.

Open Host Service a Published Language

Open Host Service je role upstreamu, který má víc konzumentů. Místo samostatné smlouvy s každým publikuje jeden stabilní protokol.

Kniha ho doporučuje zhruba od tří konzumentů. Verze patří rovnou do URL a stará s novou pak nějakou dobu běží vedle sebe.

Jen bacha na serializační skupiny v Symfony. Když query vrátí prosté pole, nic neodfiltrují a verze jedna pošle i stav skladu, který slibovala nemít. Fungují jen nad objektem, který má atribut Groups u každé vlastnosti.

Plnohodnotná integrace potřebuje k Open Host Service ještě Published Language. OHS je kanál, třeba REST nebo AMQP. Published Language je formát, tedy jak data vypadají a co znamenají, zapsaný třeba jako JSON Schema.

Schéma v knize záměrně nezakazuje neznámá pole. Konzument si přečte, co zná, a zbytek ignoruje. Nepovinné pole proto přibude ještě ve verzi jedna. Verze dva vzniká až při rozbíjející změně.

Vernon k tomu přidává pravidlo, že konzument závisí na schématu, a ne na třídách producenta. Sdílený balíček s třídami událostí je pohodlný, jenže je to skrytý Shared Kernel se všemi jeho náklady.

Context Map za 90 minut a Big Ball of Mud

Context Map nekreslí architekt o samotě. Kniha na to má workshop pro tři až osm lidí, který trvá devadesát minut a má pět kroků.

Vyjmenovat kontexty. Nakreslit šipky a pojmenovat vztahy i role. Označit upstream a downstream. Najít nebezpečná místa. A výsledek zapsat do repozitáře.

Když se tým neshodne, jestli je vztah Customer Supplier, nebo Conformist, je nedefinovaný a patří k eskalaci. Textový popis pak u každého vztahu uvádí vlastníka, kanál, frekvenci změn a eskalační kontakt.

A když mapu nejde nakreslit vůbec, máte Big Ball of Mud. Tak ten stav v roce 1997 pojmenovali Foote a Yoder. Poznáte ho podle sdílené databáze, cyklických závislostí a entit, které používá několik kontextů najednou.

Evans v DDD Reference radí něco překvapivě pasivního. Kolem celého nepořádku obtáhnout hranici a nazvat ho Big Ball of Mud. Uvnitř se nesnažit o sofistikovaný model a hlídat, aby se nerozléval do sousedních kontextů.

Ven se pak postupuje přes Strangler Fig. Čisté kontexty se vyčleňují jeden po druhém a každý chrání Anti-Corruption Layer. Prvním krokem ale není kód. Je to popisná mapa současného stavu.

Otázky a shrnutí

Krátká otázka na rozmyšlenou. Catalog posílá události do AMQP exchange a ke každé zveřejní JSON Schema. Co z toho je Open Host Service a co Published Language?

AMQP exchange je Open Host Service, tedy kanál. JSON Schema je Published Language, formát a význam zpráv. Teprve dohromady dávají plnohodnotnou integraci.

A jedna z dílu o subdoménách. Co chrání váš model u koupené Generic subdomény?

Tenký Anti-Corruption Layer. Cizí slovník zůstane za ním.

Takže v kostce. Conformist šetří překlad a platí křehkostí. Jakmile na cizích datech stojí vaše pravidla, patří na hranici Anti-Corruption Layer a jeho výstupem je vždy doménový typ.

Open Host Service je kanál, Published Language formát a bez verzování zůstane kontrakt jen deklarací. A z Big Ball of Mud se vychází popisnou mapou, kód přijde až po ní.

Příští díl je o Event Stormingu, tedy o tom, jak kontexty a jejich hranice na workshopu vůbec najít. Kapitolu o Context Mappingu najdete v knize na ddd-v-symfony.katuscak.cz.

← Všechny díly videokurzu