poniedziałek, 14 lipca 2008

Z pamiętnika zdomenowanego modelarza: #1 Anemiczny model

Jak pisałem ostatnio, przeformatowywuję się na Domain Driven Design. Co prawda książka Evansa nie jest tak dobra jak się spodziewałem, ale mimo wszystko jest wystarczająca aby stymulować do zmiany podejścia.

Postanowiłem w paru (mam nadzieję, że uda się to szybko zrobić) kolejnych krokach przedstawić kilka kluczowych różnic pomiędzy DDD a dosyć popularnym i powszechnie stosowanym podejściem quasi obiektowym.

Dziś część pierwsza: anemiczny model - to nic innego jak rekordy z Pascala albo struct z C. A gdzie logika? Oczywiście w procedurach! A że mamy języki obiektowe, to procedury nie mogą walać się nam po pamięci, więc się je opakowuje w klasy i dumnie nazywa metodami!

No dobra, z wyższego poziomu abstrakcji to nic innego jak struktury danych. Analizując problem zamieniamy rzeczowniki na klasy, rysujemy sobie kreski obrazujące powiązania. Później (o zgrozo) projektujemy sobie bazkę. Teraz już tylko wystarczy puścić jakiś generator, który wygeneruje z niej klasy mapujące Hibernate (pascal roox) i prawie z dyni. Prawie, bo został drobny szczegół - procedury. Więc potrzeba jakiegoś kontenera na procedury, w języku OO nie ma wyjścia - klasa; nazywamy ją dumnie fasadą albo servisem i piszemy sobie... switche i kaskady ifów często się przydają...
Wygenerowane klaski encji są fajne, bo mają gettery i settery do wszystkiego co jest dookoła - a nóż-widelec przyda się dla użytkownika pobrać sto tysięcy produktów jakie zamówił - heh nigdy nie wiadomo, a tak to zawsze jesteśmy otwarci na nowe ficzery.




W DDD obiekty biznesowe mają przede wszystkim odpowiedzialność. To one enkapsulują logikę biznesową czyli główną wartość naszego systemu. To przecież w tym miejscu rodzą się wszelkie problemy: bagole logiczne, powielanie kodu sprawiające ból w pupie przy refaktoryzacji - skąd my to znamy;)
To z nich możemy budować biblioteki reużywalnych komponentów biznesowych.

W DDD ważne jest aby "mówić wspólnym językiem". Czyli słownictwo z danej dziedziny powinno być używane nie tylko przez ekspertów domenowych i analityków, ale również przez projektantów i programistów. Przełożenie pomiędzy analizą a projektem powinno być dosyć spójne.

Co więcej, przy podejściu DDD na poziomie projektu/implementacji obiekty biznesowe mogą delegować wykonanie czegoś np do strategii lub w ogólności posługiwać się trikami (wzorcami) OO.

Obiekty biznesowe mają swój stan, który możemy chcieć utrwalić - wówczas mapujemy niektóre ich pola na kolumny w tabelach.

W DDD obiekty biznesowe mają owszem referencje do swych zagregowanych wnętrzności. Ale nie koniecznie po wszystkich kluczach obcych i w obie strony! W DDD istnieje pojęcie agregatu. Jest to spójna logicznie paczka obiektów, która ma roota - główny obiekt. Do głównego obiektu wysyłamy sygnały (wołamy metodę) a ten ewentualnie w swej logice zmodyfikuje stan swych zagregowanych "dzeci".

Po co zatem inne klucze obce? Po to aby zamodelować inny agregat - swego rodzaju inną perspektywę z której możemy spojrzeć na grupę obiektów.

To podejście ma niestety jedną wadę: gdy propagujemy taki obiekt biznesowy do warstwy GUI wówczas łamiemy hermetyzację warstw - gdyż wówczas metody biznesowe są wystawione dla programistów formularzy. Swoją drogą... czy w JSF czy czymś podobnym nie dałoby się tak zmontować javascript czy parametry requesta w ogólności aby odpalić jakąś metodę biznesową, która nie jest zbindowana z buttonem?
Rozwiązaniem może być przepakowywanie danych w DTOsy na potrzeby GUI - tak, tak, wiem DTO to syf, ale jak to zrobić inaczej?


//================
Pamiętam jak ok 4 lata temu nieśmiało dodałem sobie małą metodkę do klasy encji Hibernate, która niestety zniknęła przy którymś tam z kolei generowaniu klas na podstawie świeżo zmienionej bazy i wspólnie doszliśmy do wniosku, że metody w tych klasach są złe i zakazane:)

Brak komentarzy: