Po co używać DTO (Data Transfer Objects)?

132

Po co używać DTO i czy jest to przestarzała koncepcja? Używam POJO w warstwie widoku do przesyłania i utrwalania danych. Czy te POJO można uznać za alternatywę dla DTO?

Vinoth Kumar CM
źródło
10
Ale POJO może być DTO, a DTO można wdrożyć za pomocą POJO. Porównujesz jabłka i pomarańcze.
Euforyczny
3
Dlaczego dobre pomysły powinny być przestarzałe? Spójrz na Lisp. Oprócz żartów zgadzam się z Euphoric: zwykle implementuję DTO za pomocą POJO. Nadal uważam, że DTO są bardzo proste (KISS) i użyteczna koncepcja.
Giorgio
Nie ma sensu, to anty-wzorzec, patrz: Obiekt przesyłania danych to wstyd
yegor256

Odpowiedzi:

115

DTO jest wzorcem i jest niezależne od implementacji (POJO / POCO). DTO mówi, że ponieważ każde połączenie z dowolnym zdalnym interfejsem jest drogie, odpowiedź na każde połączenie powinna przynieść jak najwięcej danych. Tak więc, jeśli wymagane jest wiele żądań, aby przynieść dane dla określonego zadania, dane, które mają zostać przyniesione, można połączyć w DTO, dzięki czemu tylko jedno żądanie może przynieść wszystkie wymagane dane. Katalog wzorców architektury aplikacji korporacyjnych zawiera więcej szczegółów.

DTO to podstawowa koncepcja, nie przestarzała.

theD
źródło
9
można je jednak znaleźć pod różnymi nazwami, ponieważ wydaje się, że wszyscy
wymyślają
3
Jak „Obiekt wartości”.
theD
2
@linkerro: Prawda: Myślę, że wiele osób powinno spędzać więcej czasu na czytaniu o rzeczach, które już zostały wynalezione, zamiast samodzielnie wymyślać je na nowo. Wymyślone na nowo rzeczy zawsze będą mniej dojrzałe.
Giorgio
10
@Giorgio Istnieje wielu deweloperów, którzy wciąż biegają z pomysłami, które nigdy nie powinny odejść od podstaw. Chciałbym, aby więcej twórców kwestionowało każdy pomysł, o którym czytali.
Erik Reppen
59

Koncepcja DTO (obiekty, których celem jest zebranie danych, które mają zostać zwrócone klientowi przez serwer) z pewnością nie jest przestarzała.

Co jest nieco przestarzały jest pojęcie konieczności DTOs które zawierają żadnej logiki w ogóle, są wykorzystywane wyłącznie do przesyłania danych i „zmapowane” od obiektów domeny przed wysłaniem do klienta, a nie odwzorowany, aby wyświetlić modele przed przekazaniem ich do warstwy wyświetlacza. W prostych aplikacjach obiekty domeny często mogą być ponownie bezpośrednio używane jako DTO i przekazywane bezpośrednio do warstwy wyświetlania, dzięki czemu istnieje tylko jeden zunifikowany model danych. W przypadku bardziej złożonych aplikacji nie chcesz udostępniać całego modelu domeny klientowi, dlatego konieczne jest mapowanie modeli domeny na DTO. Posiadanie osobnego modelu widoku, który powiela dane z DTO, prawie nigdy nie ma sensu.

Jednak powodem, dla którego to pojęcie jest przestarzałe, a nie po prostu błędne, jest to, że niektóre (głównie starsze) frameworki / technologie tego wymagają, ponieważ ich domeny i modele widoków nie są POJOS i zamiast tego są bezpośrednio powiązane z frameworkiem.

Przede wszystkim komponenty Beans w J2EE przed standardem EJB 3 nie były POJO, a zamiast tego były obiektami proxy zbudowanymi przez serwer aplikacji - po prostu nie było możliwe wysłanie ich do klienta, więc nie miałeś wyboru, czy chcesz mieć oddzielną warstwę DTO - było obowiązkowe.

Michael Borgwardt
źródło
2
Jako twórca interfejsu użytkownika zmuszony do pełnienia bardziej ogólnej roli, zdecydowanie znalazłem zjawisko Mapper.Map w naszej bazie kodu oszałamiające. Dlaczego DTO nie może po prostu zmapować się?
Erik Reppen
1
@ErikReppen Główną korzyścią jest oddzielenie modeli domen i DTO. Jeśli Twoje DTO mapuje się, potrzebuje odniesienia do modeli Twojej domeny.
Alexander Derck
17

Chociaż DTO nie jest przestarzałym wzorcem, często stosuje się go niepotrzebnie, co może sprawiać wrażenie, że jest przestarzały.

Najczęściej używanym wzorcem w społeczności Java Enterprise jest DTO. DTO zostało jasno zdefiniowane jako rozwiązanie problemu dystrybucji. DTO miał być gruboziarnistym kontenerem danych, który skutecznie przenosi dane między procesami (poziomami). ~ Adam Bien

Załóżmy na przykład, że masz JSF ManagedBean. Często zadawane jest pytanie, czy komponent bean powinien zawierać odniesienie do encji JPA bezpośrednio, czy też powinien zachować odniesienie do jakiegoś obiektu pośredniego, który później przekształca się w encję. Słyszałem, że ten obiekt pośredni nazywany jest DTO, ale jeśli komponenty ManagedBeans i podmioty działają w ramach tej samej maszyny JVM, korzystanie z wzorca DTO jest niewielkie.

Zastanów się nad adnotacjami sprawdzania poprawności komponentu. Twoje podmioty JPA są prawdopodobnie opatrzone adnotacjami przy użyciu sprawdzania poprawności @NotNull i @Size. Jeśli korzystasz z DTO, będziesz chciał powtórzyć te weryfikacje w swoim DTO, aby klienci korzystający ze zdalnego interfejsu nie musieli wysyłać wiadomości, aby dowiedzieć się, że nie udało im się przeprowadzić podstawowej weryfikacji. Wyobraź sobie całą tę dodatkową pracę polegającą na kopiowaniu adnotacji Bean Validation między DTO i Entity, ale jeśli Twój Widok i Encje działają w ramach tej samej JVM, nie musisz podejmować się tej dodatkowej pracy: po prostu użyj Encji.

Łącze IAmTheDude do katalogu wzorców architektury aplikacji korporacyjnych zawiera zwięzłe wyjaśnienie DTO, a oto inne referencje, które uznałem za pouczające:

DavidS
źródło
3
Jest takie zdanie: „... ale jeśli komponenty ManagedBeans i jednostki działają w ramach tej samej maszyny JVM, korzystanie z wzorca DTO jest niewielkie . Istnieje wiele średnich aplikacji w firmach, które głupio wdrażają wzorzec DTO bez żadnych korzyści. Po prostu dodaje bezużyteczną „warstwę kopiowania”. Ludzie, którzy stworzyli te systemy, nie zdawali sobie sprawy, że menedżer encji Java EE 5+ oddziela jednostki po zakończeniu transakcji i czyni je rzeczywistymi DTO. W przypadku aplikacji internetowych z pojedynczą maszyną JVM rodzaj wzorca jest przestarzały . Wygląda na to, że jest reliktem programistów zaplecza J2EE ...
Kawu,
Ale czym jest „JSF ManagedBean” i „JPA Entity”? Jeśli nie są one nieaktualne, powinieneś być w stanie wyjaśnić je przy użyciu terminów agnostycznych dotyczących języka i języka.
U Avalos,
8

Absolutnie nie! Niedawno nauczyłem się lekcji na temat lepszego używania DTO zamiast twojego obiektu biznesowego, którego używasz (być może powiązanego z maperem ORM).

Jednak używaj ich tylko wtedy, gdy są odpowiednie do użycia, a nie tylko ze względu na ich użycie, ponieważ są wymienione w dobrym wzorcu.
Typowy przykład, jaki przychodzi mi na myśl, to ujawnienie jakiegoś interfejsu stronom trzecim. W takim scenariuszu chciałbyś utrzymać wymieniane obiekty na dość stabilnym poziomie, co zwykle możesz osiągnąć ładnie dzięki DTO.

Juri
źródło
1

Jednym z miejsc, które według mnie są szczególnie przydatne, jest zawarcie logiki dla odpowiedzi API. Za pomocą tego wzorca łatwo jest zarządzać różnymi typami odpowiedzi od obiektów do różnych formatów w testowany sposób. Korzystając z tego wzorca na mojej obecnej roli, mogliśmy rozpocząć testowanie formatów odpowiedzi dla naszych interfejsów API, co było cenne, ponieważ nasz stos staje się coraz bardziej izomorficzny dla różnych klientów (http / mobile). Zdecydowanie nieaktualne.

zquintana
źródło