sobota 10. října 2009

Chudokrevný model, chudý příbuzný objektově orientovaného návrhu?

Nedávno se mě jeden kolega zeptal jestli budeme mít anemic domain model (chudokrevný?). Byl jsem trošku v rozpacích co tím myslí. Po krátke diskuzi jsme si vyjasnili termíny (problém jsem znal, ale termín jsem zapomněl) a já jsem prohodil, že asi budeme. Když nad tím přemýšlím, musím říci, že to byla blbost.

Pokud si přečtete výše uvedeny článek Martina Fowlera dostane se vám erudovaného vysvětlení co to je chudokrevný doménový model model. Pokud to dělat nechcete, pak se budete muset spokojit s mojí interpretací. Chudokrevný doménový model je takový model, kdy doménové třídy reprezentující business entity systému neobsahují žadnou logiku. Jsou to pouze "přenosky" dat se settry a gettry.

Fowler dále správně upozorňuje na fakt, že chudokrevný doménový model vede k příliš těžkopádné a tlusté aplikační vrstvě. V té se mísí všechna aplikační logika namísto toho, aby ležela právě v doménovém modelu kam patří. Pokud jste v posledních pár letech dělali nějakou vícevrstvou aplikaci, pak se schválně podívejte na velikost všech tříd, které v názvu obsahují slovo Service. Jsou to u vás největší molochy v celém projektu jako u mě?

Problém s těmito molochy je v tom, že jsou jenom velice těžce jakýmkoliv způsobem refaktorovatelné. Samozřejmě pokud pominu fakt, že z metody o pětsistech řádcích uděláme pět malých o sto řádcích. Představa nějakého objektového re-designu je skoro nemožná.

Každý chytrý J2EE tutoriál či článek nám radí jak je dobré členit náš program do vrstev. Máme tak vrstvu servisní (aplikační logiky), vrstvu prezentační a vrstvu persistence (ukládání dat). Bohužel už nikde, až na pár míst, se nedočteme jak správně by měly tyto vrstvy vypadat. Výsledkem je, že sice správně separuje kód se stejnou odpovědností (UI, persistence), ale neděláme to objektově správně. Ve smyslu, že kód který patří do doménového modelu daváme do vrstev kam vůbec nepatří.

Jenže co to je objektově správně a potřebujeme to vůbec? Dokázali jsme žít se špatným objektovým návrhem léta a naše programy fungovaly dobře. Ovšem to by neměl být důvod nesnažit se jejich strukturu zlepšit, pokud víme, že je něco špatně. Hodně jsem přemýšlel o tom jakým způsobem to udělat a přijde mi, že nejlépe to řeší Domain Driven Design (zkráceně DDD).

Klíčove je, že aplikačni logika, která leží v servisné vrstvě, nebo nedej bože ve vrstvě persistence, se přesune do doménových tříd. To neznamená ovšem, že by najednou měla každá z těchto tříd vědět jakým způsobem se má uložit do databáze nebo snad ovládat transakční logiku. Doménové třídy například požadavek na uložení delegují na vrstvu persistence.

Servisní vrstva a vstva pro ukládání dat by měla zůstat co nejtenčí. V podstatě to znamená, že slouží jenom k tomu, aby došlo k správnému překladu jedné objektové reprezentace na druhou a kordinaci s infrastrukturou. Nemyslim si, že je jednoduché takto aplikace vytvářet. Největší problém je v tom, že s doménovými třídami nakládáme obvykle v kódu jinak než s třídami jiných vrstev.

Třidy z doménového modelu vytváříme povětšinou konstruktorem. V takovém případě máme problém jak do nich dostat právě třídy jiných vrstev. No ale to už je na jiný článek.

Na závěr dám k dobru ješte pár dobrých článků k tématu