Domain object vs Transfer object rozważania

0

Mam mętlik w głowie jeśli chodzi o wzorce Domain Object, Transfer Object itd. Postaram się w jak najprostrzy sposób opisać o co chodzi.
Otóż w książce "Core Java EE Patterns", jest napisane m.in : "Komponenty Entity prowadzają znacznie większy narzut niż zwykłe obiekty Javy. Wywołania metod tych komponentów są wywołaniami zdalnymi, a więc powodują dodatkowy ruch w sieci. Poza tym komponenty te muszą korzystać z zewnętrznych źródeł danych", lub np. "Komponenty Entity to najczęściej duże, trwałe obiekty rozproszone. Udostępnienie tych komponentów klientom w innych warstwach powoduje wzrost narzutu wprowadzanego przez sieć i zmniejszenie wydajności " itd itd. Ogólnie przedstawiony jest też wzorzec gdzie DAO ma zwracać obiekt transferowyTO (Transfer object), a nie komponent entity str 385.

Natomiast przeglądając sobie wzorce tworzenia aplikacji w springu (w załączniku) , lub też z tej strony: http://gordondickens.com/wordpress/2012/07/08/enterprise-spring-best-practices-part-2-application-architecture/ . Widzimy, że obiekt domeny przechodzi przez wszystkie warstwy. Podobnie jest jak czytam książke spring data tam DAO (Repositories np. CrudRepositories) zwracają obiekty domeny oraz mają domyślnie transakcje !!!.

Według mnie propagacja obiektu domeny powyżej DAO nie ma sensu. Po pierwsze zawsze obiekt domeny tworzymy pod dane rozwiazanie np. JPA, MongoDB, Neo4J itd. Zawsze użyjemy troche odmiennego modelowania biorąc pod uwagę dobre/ złe strony danego rozwiązania. Dodajemy także odpowiednie adnotacje inne np . dla jpa inne dla mongo itd. Dlatego jeśli będziemy chcieli zmienić providera w warstwie integracyjnej to mamy duużo pracy, bo nasz obiekt domeny jest na wszystkich warstwach. Tego problemu nie mamy jeśli użyjemy obiektu transferu, tworzymy taki obiekt i tyle jego rozdzajów w zależności jakie informacje chcemy wyciągnąć, następnie dostosowujemy konwersje pomiędzy domain object, a data object. Czyli nasze warstwy są niezależne od siebie dzieli je tylko Transfer Object.

Problemem mogą być transakcje, i leniwe ładowanie w przypadku jpa. Musimy mieć transakcje na poziomie DAO, aby leniwie dociągnąć sobie dane.

Pojawiają się jednak następujące pytania.

  • Przecież w rozwiązaniach opartych na nosql nie używamy encji, kontener (serwer) nie zarządza nimi, korzystamy za to z innych mechanizmów, np. JDO i wzbogacanie klas. Czy wtedy nasz obiekt domeny jest już lżejszy ?

  • Gdybyśmy propagowali nasz domain object do warstwy prezentacji, moglibyśmy wykorzystać leniwe ładowanie i fajnie dociągać sobie informacje w warstwie prezentacji ?

Jak widać jestem troszkę zamieszany w tym temacie, Zwłąszcza jest dla mnie dziwne tak jak piszą w publikacjach np. książka Spring Data, piszą, żeby w obiektach domenowych nie używać np. klasy ObjectID bo jest specyficzna dla mongoDB. No ale przecież tak jak pisałem wcześniej, nie da się stworzyć obiektu domeny który będzie ewentualnie pasował do wszystkich rozwiązań, zawsze wzbogacamy klasę adnotacjami , używamy innych trików bo np. w mongoDB mapa jest czymś naturalnym a w mysql już musimy inaczej, opatrzyć ją adnotacją itd. Dlatego jest dla mnie bez sensu propagowanie "uniwersalnego" domain object. :/

0

Mam za mało czasu zeby się odnieść do całości ale:

Gdybyśmy propagowali nasz domain object do warstwy prezentacji, moglibyśmy wykorzystać leniwe ładowanie i fajnie dociągać sobie informacje w warstwie prezentacji ?

Teoretycznie tak, ale tylko jeśli sesja nadal byłaby otwarta. Inaczej dostałbyś LazyInitializationException bo "dociągnąć" możesz tylko do czasu kiedy sesja w której wyciągnąłeś obiekt z bazy nadal jest aktywna. Ogólnie Open-Session-in-View nie jest specjalnie eleganckie i wprowadza pewne komplikacje wydajnościowe. Zresztą wydaje mi się że rzadko kiedy takie rozwiązanie faktycznie jest potrzebne.

edit:
Wracając do tematu, otóż nikt zwykle nie przejmuje się tym że "teoretycznie" mógłby wymienić warstwę domain objectów na jakąś zupełnie inną. Nawet kiedy ktoś używa JPA to zwykle wybiera jednego dostawcę i się go trzyma. Niby teoretycznie można by prawie bezboleśnie dostawcę zmienić, ale w praktyce nigdy takiej sytuacji nie widziałem. O wymianie warstwy z SQL na noSQL to już w ogóle :D Stąd też większość tutoriali/dokumentacji/publikacji w ogóle takiej sytuacji nie bierze pod uwagę.
Gdybyś jednak bardzo bardzo chciał tak zrobić to wtedy faktycznie potrzebujesz pośrednią warstwę obiektów, które w praktyce będą kalką obiektów domenowych ale bez adnotacji. Zadaj sobie tylko pytanie czy faktycznie jest ci to potrzebne do czegokolwiek :)

0

Z tego co pamiętam Adam Bien rozprawiał się z tym tematem trochę na tegorocznym InfoShare, nie wiem czy jest gdzieś już wideo czy nie (możliwe, że było to na warsztatach a nie na prezentacji). Zresztą odnosi się zdaje się do tematu szerzej w Real World Java EE Patterns-Rethinking Best Practices które w skrócie zostały podsumowane np, tutaj: https://docs.google.com/document/d/1RDNH0SBCWdRkVFaJc9DwuB0RRxU4tT2P5mINaE3aKJM/preview

0

Weź sobie coś więcej niż Spring, np. takie JEE i wtedy DTO ma sens.
Zdalnemu klientowi nie przekażesz obiektu domenowego, po prostu się nie da!

0
Wybitny Pomidor napisał(a):

Zdalnemu klientowi nie przekażesz obiektu domenowego, po prostu się nie da!

Kiedyś tak robiono.

1

W sumie to może się i da, tylko co z tego.
Jeśli utrwalanie obiektów załatwia JPA, to przekazanie ich poza kontekst kontenera jest bez sensu.
Poza tym, DTO mają inne zalety np. żeby udostępnić listę faktur nie trzeba "tarmosić" wszystkich atrybutów faktury, danych płatnika i pewnie wielu innych. W DTO umieszczę się tylko to (tylko te pola) co Klientowi jest potrzebne na liście faktur. Narzut jest na dodatkową pracę ale ruch sieciowy mniejszy.
Co więcej DTO może być wiele, każdy do innych celów, nie zaśmiecamy modelu domeny.
Trzeba tylko zacząć trochę inaczej myśleć, np. o tym, że Klient nie zawsze jest przeglądarką WWW, a wszystkie zapytania obsłużą serwlety. Czasem Klient musi być "zwykłą" aplikacją desktopową.

0
Wybitny Terrorysta napisał(a):

W sumie to może się i da, tylko co z tego.
Jeśli utrwalanie obiektów załatwia JPA, to przekazanie ich poza kontekst kontenera jest bez sensu.
(...)
Trzeba tylko zacząć trochę inaczej myśleć, np. o tym, że Klient nie zawsze jest przeglądarką WWW, a wszystkie zapytania obsłużą serwlety. Czasem Klient musi być "zwykłą" aplikacją desktopową.

Właśnie to był jeden z większych ficzerów EJB- umożliwiały z poziomu aplikacji desktopowych i apletów pracę ze zdalnymi obiektami, i to w transakcjach. Jak dla mnie to było całkiem fajne :P
Encyjne EJB są już i tak wycofane, po części wyparte właśnie przez JPA. I chyba autor tego wątku (tak widzę 2013 ale nie ja odgrzebałem) pomylił encyjne EJB z encjami JPA.

0
 
Musimy mieć transakcje na poziomie DAO, aby leniwie dociągnąć sobie dane.  

Co?

1 użytkowników online, w tym zalogowanych: 0, gości: 1