Domain object vs Transfer object rozważania

Domain object vs Transfer object rozważania
L4
  • Rejestracja:około 15 lat
  • Ostatnio:11 miesięcy
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. :/

edytowany 1x, ostatnio: lukasw44
Shalom
  • Rejestracja:około 21 lat
  • Ostatnio:prawie 3 lata
  • Lokalizacja:Space: the final frontier
  • Postów:26433
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 :)


"Nie brookliński most, ale przemienić w jasny, nowy dzień najsmutniejszą noc - to jest dopiero coś!"
edytowany 1x, ostatnio: Shalom
L4
Dzięki zastanawiam się tylko dlaczego w publikacjach odnośnie springa zawsze domain object przecina wszystkie warstwy, tak jak jest w załączniku ?? Czy ogólnie trzymać sie zasady, że dao ma zwracać Transfer object czy dopiero warstwa serwisów ??
Shalom
edytowałem posta ;)
airborn
  • Rejestracja:ponad 15 lat
  • Ostatnio:prawie 7 lat
  • Postów:274
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

L4
Dzięki. Można wnioskować, że Transfer Object bardzo dobrze pasuje do tworzenia aplikacji w architekturze SOA, natomiast inaczej jest w architekturze DDD gdzie używa się go w warstwie prezentacji.
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!

SP
  • Rejestracja:ponad 9 lat
  • Ostatnio:ponad 2 lata
  • Postów:127
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ą.

SP
  • Rejestracja:ponad 9 lat
  • Ostatnio:ponad 2 lata
  • Postów:127
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.

S9
  • Rejestracja:ponad 10 lat
  • Ostatnio:5 miesięcy
  • Lokalizacja:Warszawa
  • Postów:3573
0
Kopiuj
 
Musimy mieć transakcje na poziomie DAO, aby leniwie dociągnąć sobie dane.  

Co?


"w haśle <młody dynamiczny zespół> nie chodzi o to ile masz lat tylko jak często zmienia się skład"
Kliknij, aby dodać treść...

Pomoc 1.18.8

Typografia

Edytor obsługuje składnie Markdown, w której pojedynczy akcent *kursywa* oraz _kursywa_ to pochylenie. Z kolei podwójny akcent **pogrubienie** oraz __pogrubienie__ to pogrubienie. Dodanie znaczników ~~strike~~ to przekreślenie.

Możesz dodać formatowanie komendami , , oraz .

Ponieważ dekoracja podkreślenia jest przeznaczona na linki, markdown nie zawiera specjalnej składni dla podkreślenia. Dlatego by dodać podkreślenie, użyj <u>underline</u>.

Komendy formatujące reagują na skróty klawiszowe: Ctrl+B, Ctrl+I, Ctrl+U oraz Ctrl+S.

Linki

By dodać link w edytorze użyj komendy lub użyj składni [title](link). URL umieszczony w linku lub nawet URL umieszczony bezpośrednio w tekście będzie aktywny i klikalny.

Jeżeli chcesz, możesz samodzielnie dodać link: <a href="link">title</a>.

Wewnętrzne odnośniki

Możesz umieścić odnośnik do wewnętrznej podstrony, używając następującej składni: [[Delphi/Kompendium]] lub [[Delphi/Kompendium|kliknij, aby przejść do kompendium]]. Odnośniki mogą prowadzić do Forum 4programmers.net lub np. do Kompendium.

Wspomnienia użytkowników

By wspomnieć użytkownika forum, wpisz w formularzu znak @. Zobaczysz okienko samouzupełniające nazwy użytkowników. Samouzupełnienie dobierze odpowiedni format wspomnienia, zależnie od tego czy w nazwie użytkownika znajduje się spacja.

Znaczniki HTML

Dozwolone jest używanie niektórych znaczników HTML: <a>, <b>, <i>, <kbd>, <del>, <strong>, <dfn>, <pre>, <blockquote>, <hr/>, <sub>, <sup> oraz <img/>.

Skróty klawiszowe

Dodaj kombinację klawiszy komendą notacji klawiszy lub skrótem klawiszowym Alt+K.

Reprezentuj kombinacje klawiszowe używając taga <kbd>. Oddziel od siebie klawisze znakiem plus, np <kbd>Alt+Tab</kbd>.

Indeks górny oraz dolny

Przykład: wpisując H<sub>2</sub>O i m<sup>2</sup> otrzymasz: H2O i m2.

Składnia Tex

By precyzyjnie wyrazić działanie matematyczne, użyj składni Tex.

<tex>arcctg(x) = argtan(\frac{1}{x}) = arcsin(\frac{1}{\sqrt{1+x^2}})</tex>

Kod źródłowy

Krótkie fragmenty kodu

Wszelkie jednolinijkowe instrukcje języka programowania powinny być zawarte pomiędzy obróconymi apostrofami: `kod instrukcji` lub ``console.log(`string`);``.

Kod wielolinijkowy

Dodaj fragment kodu komendą . Fragmenty kodu zajmujące całą lub więcej linijek powinny być umieszczone w wielolinijkowym fragmencie kodu. Znaczniki ``` lub ~~~ umożliwiają kolorowanie różnych języków programowania. Możemy nadać nazwę języka programowania używając auto-uzupełnienia, kod został pokolorowany używając konkretnych ustawień kolorowania składni:

```javascript
document.write('Hello World');
```

Możesz zaznaczyć również już wklejony kod w edytorze, i użyć komendy  by zamienić go w kod. Użyj kombinacji Ctrl+`, by dodać fragment kodu bez oznaczników języka.

Tabelki

Dodaj przykładową tabelkę używając komendy . Przykładowa tabelka składa się z dwóch kolumn, nagłówka i jednego wiersza.

Wygeneruj tabelkę na podstawie szablonu. Oddziel komórki separatorem ; lub |, a następnie zaznacz szablonu.

nazwisko;dziedzina;odkrycie
Pitagoras;mathematics;Pythagorean Theorem
Albert Einstein;physics;General Relativity
Marie Curie, Pierre Curie;chemistry;Radium, Polonium

Użyj komendy by zamienić zaznaczony szablon na tabelkę Markdown.

Lista uporządkowana i nieuporządkowana

Możliwe jest tworzenie listy numerowanych oraz wypunktowanych. Wystarczy, że pierwszym znakiem linii będzie * lub - dla listy nieuporządkowanej oraz 1. dla listy uporządkowanej.

Użyj komendy by dodać listę uporządkowaną.

1. Lista numerowana
2. Lista numerowana

Użyj komendy by dodać listę nieuporządkowaną.

* Lista wypunktowana
* Lista wypunktowana
** Lista wypunktowana (drugi poziom)

Składnia Markdown

Edytor obsługuje składnię Markdown, która składa się ze znaków specjalnych. Dostępne komendy, jak formatowanie , dodanie tabelki lub fragmentu kodu są w pewnym sensie świadome otaczającej jej składni, i postarają się unikać uszkodzenia jej.

Dla przykładu, używając tylko dostępnych komend, nie możemy dodać formatowania pogrubienia do kodu wielolinijkowego, albo dodać listy do tabelki - mogłoby to doprowadzić do uszkodzenia składni.

W pewnych odosobnionych przypadkach brak nowej linii przed elementami markdown również mógłby uszkodzić składnie, dlatego edytor dodaje brakujące nowe linie. Dla przykładu, dodanie formatowania pochylenia zaraz po tabelce, mogłoby zostać błędne zinterpretowane, więc edytor doda oddzielającą nową linię pomiędzy tabelką, a pochyleniem.

Skróty klawiszowe

Skróty formatujące, kiedy w edytorze znajduje się pojedynczy kursor, wstawiają sformatowany tekst przykładowy. Jeśli w edytorze znajduje się zaznaczenie (słowo, linijka, paragraf), wtedy zaznaczenie zostaje sformatowane.

  • Ctrl+B - dodaj pogrubienie lub pogrub zaznaczenie
  • Ctrl+I - dodaj pochylenie lub pochyl zaznaczenie
  • Ctrl+U - dodaj podkreślenie lub podkreśl zaznaczenie
  • Ctrl+S - dodaj przekreślenie lub przekreśl zaznaczenie

Notacja Klawiszy

  • Alt+K - dodaj notację klawiszy

Fragment kodu bez oznacznika

  • Alt+C - dodaj pusty fragment kodu

Skróty operujące na kodzie i linijkach:

  • Alt+L - zaznaczenie całej linii
  • Alt+, Alt+ - przeniesienie linijki w której znajduje się kursor w górę/dół.
  • Tab/⌘+] - dodaj wcięcie (wcięcie w prawo)
  • Shit+Tab/⌘+[ - usunięcie wcięcia (wycięcie w lewo)

Dodawanie postów:

  • Ctrl+Enter - dodaj post
  • ⌘+Enter - dodaj post (MacOS)