Co to jest obiekt transferu danych?

218

Co to jest obiekt transferu danych?

Czy w MVC są klasy modeli DTO, a jeśli nie, jakie są różnice i czy potrzebujemy obu?

Yaron Naveh
źródło
@ yegor256 i fakt, że książka w tym artykule wie, jak pobrać dane z API, a także jak przechowywać dane w DB, a więc naruszając SRP, jest w porządku?
Betlista

Odpowiedzi:

222

Obiekt przenoszenia danych to obiekt służący do kapsułkowania danych i wysyłania ich z jednego podsystemu aplikacji do innego.

DTO są najczęściej używane przez warstwę usług w aplikacji N-Tier do przesyłania danych między sobą a warstwą interfejsu użytkownika. Główną zaletą jest to, że zmniejsza ilość danych, które muszą być przesyłane przewodowo w aplikacjach rozproszonych. Tworzą również świetne modele we wzorze MVC.

Innym zastosowaniem DTO może być kapsułkowanie parametrów dla wywołań metod. Może to być przydatne, jeśli metoda wymaga więcej niż 4 lub 5 parametrów.

Korzystając ze wzoru DTO, można również skorzystać z asemblerów DTO. Asemblery są używane do tworzenia DTO z Domen i odwrotnie.

Konwersja z Domain Object do DTO iz powrotem może być kosztownym procesem. Jeśli nie tworzysz aplikacji rozproszonej, prawdopodobnie nie zobaczysz żadnych wielkich korzyści z tego wzoru, jak wyjaśnia tutaj Martin Fowler

Benny Hallett
źródło
7
„DTO tworzy świetne modele we wzorze MVC” - ale czy model nie powinien zawierać wszystkich danych obiektu i DTO powinien być zoptymalizowany z częścią danych? Jeśli mam model A i muszę przekazać go do dwóch podsystemów, czy będą A_DTO_1 i A_DTO_2 z odpowiednimi polami dla każdego z nich? „DTO może obejmować enkapsulację parametrów dla wywołań metod” -> Czy więc każda klasa, która otacza parametry, to DTO, nawet jeśli nie jest to system rozproszony? Czy modele w MVC nie są obiektem domeny?
Yaron Naveh
2
W odpowiedzi na twoje pierwsze pytanie, nie sądzę, żeby mówili o tym samym. Model w MVC niekoniecznie musi być klasą z Twojego modelu domeny. To powiedziawszy, może być. Korzystanie z DTO usuwa wszystkie niepotrzebne rzeczy. Zależy tylko od architektury, której szukasz. Nie jestem pewien, jak dokładnie odpowiedzieć na drugie pytanie. Niezależnie od tego, czy jest to połączenie, czy nie, wciąż jest to obiekt, który enkapsuluje wiązkę danych, które mają być przesyłane między (pod) systemami, więc twierdzę, że to DTO.
Benny Hallett,
12
„Innym zastosowaniem DTO może być enkapsulacja parametrów dla wywołań metod. Może to być przydatne, jeśli metoda przyjmuje więcej niż 4 lub 5 parametrów.” W rzeczywistości jest to anty-wzorzec zwany klasą Poltergeist lub Cygańskiego Wozu. Jeśli twoja metoda potrzebuje 4 argumentów, to daj jej 4, nie twórz klasy tylko po to, aby przenieść obiekt do metody lub klasy.
Wix,
2
@ Wix, dobra uwaga. Twierdziłbym jednak, że jest to w porządku, jeśli jest poprawne semantycznie (powiedzmy, jeśli przekazujesz klasę ustawień z właściwościami, a nie same właściwości jako wartości). To, czego nie powinieneś robić, to wrzucać wszystkie argumenty w celu przekazania pojedynczego obiektu, ponieważ mogą one być bardzo niezwiązane i powodować późniejsze koszmary.
Aram Kocharyan,
3
DTOs nie powinny być używane do enkapsulacji parametrów dla wywołań metod (co czyniłoby je LocalDTO), zostały wprowadzone w kontekście zdalnych interfejsów: martinfowler.com/bliki/LocalDTO.html
Rui
28

Definicja DTO znajduje się na stronie Martina Fowlera . DTO są używane do przesyłania parametrów do metod i jako typy zwracane. Wiele osób korzysta z nich w interfejsie użytkownika, ale inni nadmuchują z nich obiekty domeny.

blu
źródło
22

DTO jest głupim obiektem - po prostu przechowuje właściwości i ma metody pobierające i ustawiające, ale nie ma innej logiki o dowolnym znaczeniu (może innej niż implementacja porównania () lub równości ()).

Zazwyczaj klasami modeli w MVC (przy założeniu .NET MVC tutaj) są DTO lub kolekcje / agregaty DTO

Eric Petroelje
źródło
3
Opisujesz LocalDTO: martinfowler.com/bliki/LocalDTO.html
Rui
3
Jednym z przypadków, w których warto zastosować coś takiego jak DTO, jest znaczące niedopasowanie między modelem w warstwie prezentacji a podstawowym modelem domeny. W takim przypadku sensowne jest stworzenie fasady / bramy specyficznej dla prezentacji, która mapuje z modelu domeny i przedstawia interfejs, który jest wygodny do prezentacji.
Amitābha,
14

Ogólnie obiekty wartości powinny być niezmienne. Jak obiekty całkowite lub łańcuchowe w Javie. Możemy ich używać do przesyłania danych między warstwami oprogramowania. Jeśli warstwy oprogramowania lub usługi działają w różnych zdalnych węzłach, takich jak środowisko mikrousług lub starsza aplikacja Java Enterprise. Musimy wykonać prawie dokładne kopie dwóch klas. To tam poznaliśmy DTO.

|-----------|                                                   |--------------|
| SERVICE 1 |--> Credentials DTO >--------> Credentials DTO >-- | AUTH SERVICE |
|-----------|                                                   |--------------|

W starszych wersjach oprogramowania Java Enterprise Systems DTO mogą zawierać różne elementy EJB.

Nie wiem, czy to najlepsza praktyka, czy nie, ale osobiście używam obiektów wartości w moich projektach Spring MVC / Boot takich jak to:

        |------------|         |------------------|                             |------------|
-> Form |            | -> Form |                  | -> Entity                   |            |
        | Controller |         | Service / Facade |                             | Repository |
<- View |            | <- View |                  | <- Entity / Projection View |            |
        |------------|         |------------------|                             |------------|

Warstwa kontrolera nie wie, jakie są byty. Komunikuje się z obiektami Form i View Value Objects . Form Objects ma adnotacje walidacyjne JSR 303 (na przykład @NotNull), a obiekty View Value mają adnotacje Jacksona do niestandardowej serializacji. (na przykład @JsonIgnore)

Warstwa usługi komunikuje się z warstwą repozytorium za pomocą obiektów obiektów. Obiekty encji zawierają adnotacje JPA / Hibernate / Spring Data. Każda warstwa komunikuje się tylko z dolną warstwą. Komunikacja między warstwami jest zabroniona z powodu zależności cyklicznej / cyklicznej.

User Service ----> XX CANNOT CALL XX ----> Order Service

Niektóre frameworki ORM mają możliwość projekcji za pomocą dodatkowych interfejsów lub klas. Dzięki temu repozytoria mogą zwracać Wyświetl obiekty bezpośrednio. Tam dla ciebie nie potrzebujesz dodatkowej transformacji.

Na przykład jest to nasza jednostka użytkownika:

@Entity
public final class User {
    private String id;
    private String firstname;
    private String lastname;
    private String phone;
    private String fax;
    private String address;
    // Accessors ...
}

Powinieneś jednak zwrócić Paginowaną listę użytkowników, która zawiera tylko identyfikator, imię i nazwisko. Następnie możesz utworzyć obiekt wartości widoku dla projekcji ORM.

public final class UserListItemView {
    private String id;
    private String firstname;
    private String lastname;
    // Accessors ...
}

Możesz łatwo uzyskać paginowany wynik z warstwy repozytorium. Dzięki wiośnie możesz także używać tylko interfejsów do projekcji.

List<UserListItemView> find(Pageable pageable);

Nie martw się, ponieważ inne operacje konwersji działają BeanUtils.copydobrze.

Fırat KÜÇÜK
źródło
11
  1. Według mnie najlepszą odpowiedzią na pytanie, czym jest DTO, jest to, że DTO to proste obiekty, które nie powinny zawierać żadnej logiki biznesowej ani metod implementacji, które wymagałyby testowania .
  2. Zwykle twój model (wykorzystujący wzorzec MVC) jest inteligentnym modelem i może zawierać wiele / niektóre metody, które wykonują różne operacje dla tego modelu (nie logiki biznesowej, powinno to być na kontrolerach). Jednak podczas przesyłania danych (np. Wywoływania gdzieś punktu końcowego REST ( GET/ POST/ cokolwiek) lub korzystania z usługi internetowej za pomocą SOA itp.) Nie chcesz przesyłać dużego obiektu z kodem, który nie jest konieczny do punkt końcowy zużyje dane i spowolni transfer.
Thiago Burgos
źródło
Dlaczego logika biznesowa powinna być w kontrolerach?
AlexioVay
6

Dzięki MVC obiekty przesyłania danych są często używane do mapowania modeli domen na prostsze obiekty, które ostatecznie zostaną wyświetlone przez widok.

Z Wikipedii :

Obiekt przesyłania danych (DTO), wcześniej znany jako obiekty wartości lub VO, to wzorzec projektowy używany do przesyłania danych między podsystemami aplikacji. DTO są często używane w połączeniu z obiektami dostępu do danych w celu pobierania danych z bazy danych.

Dan
źródło
3
Obiekt wartości nie jest DTO .
coderpc
0

Obiekt przesyłania danych (DTO) opisuje „obiekt, który przenosi dane między procesami” (Wikipedia) lub „obiekt, który jest używany do kapsułkowania danych i wysyłania ich z jednego podsystemu aplikacji do innego” (odpowiedź Przepełnienie stosu).

mostafa kazemi
źródło
0

DefN

DTO jest zakodowanym modelem danych. Rozwiązuje jedynie problem modelowania rekordu danych obsługiwanego przez zakodowany na stałe proces produkcyjny, w którym wszystkie pola są znane w czasie kompilacji, a zatem są dostępne za pośrednictwem silnie typowanych właściwości.

Natomiast model dynamiczny lub „torba właściwości” rozwiązuje problem modelowania rekordu danych, gdy proces produkcyjny jest tworzony w czasie wykonywania.

Cvar

DTO można modelować za pomocą pól lub właściwości, ale ktoś wynalazł bardzo przydatny kontener danych o nazwie Cvar. Jest to odniesienie do wartości. Gdy model DTO jest modelowany za pomocą właściwości , które nazywam właściwościami referencyjnymi , moduły można skonfigurować tak, aby współużytkowały pamięć sterty, a tym samym współpracowały z nią. To całkowicie eliminuje przekazywanie parametrów i komunikację O2O z twojego kodu. Innymi słowy, DTO posiadające właściwości referencyjne pozwalają kodowi na osiągnięcie zerowego sprzężenia .

    class Cvar { ... }

    class Cvar<T> : Cvar
    {
        public T Value { get; set; }
    }

    class MyDTO
    {
        public Cvar<int> X { get; set; }
        public Cvar<int> Y { get; set; }
        public Cvar<string> mutableString { get; set; } // >;)
    }

Źródło: http://www.powersemantics.com/

Dynamiczne DTO są niezbędnym składnikiem oprogramowania dynamicznego. Aby utworzyć instancję procesu dynamicznego, jednym krokiem kompilatora jest powiązanie każdej maszyny w skrypcie z właściwościami referencyjnymi zdefiniowanymi przez skrypt. Dynamiczne DTO jest budowane przez dodanie Cvars do kolekcji.

    // a dynamic DTO
    class CvarRegistry : Dictionary<string, Cvar> { }

Spory

Uwaga: ponieważ Wix oznaczył użycie DTO do organizowania parametrów jako „anty-wzór”, wydam wiarygodną opinię.

    return View(model);  // MVC disagrees

Moja architektura współpracy zastępuje wzorce projektowe. Zobacz moje artykuły internetowe.

Parametry zapewniają natychmiastową kontrolę maszyny stosu ram. Jeśli korzystasz z ciągłej kontroli, a zatem nie potrzebujesz natychmiastowej kontroli, twoje moduły nie potrzebują parametrów. Moja architektura nie ma. Konfiguracja procesowa maszyn (metod) zwiększa złożoność, ale także wartość (wydajność), gdy parametry są typami wartości. Jednak parametry typu odwołania powodują, że konsument powoduje i tak brak pamięci podręcznej w celu pobrania wartości ze sterty - dlatego wystarczy skonfigurować konsumenta za pomocą właściwości odwołania. Fakt z inżynierii mechanicznej: poleganie na parametrach jest rodzajem wstępnej optymalizacji, ponieważ samo przetwarzanie (wytwarzanie komponentów) jest marnotrawstwem. Więcej informacji można znaleźć w moim artykule W. http://www.powersemantics.com/w.html .

Fowler i firma mogą zdać sobie sprawę z korzyści DTO poza architekturą rozproszoną, jeśli kiedykolwiek znają jakąkolwiek inną architekturę. Programiści znają tylko systemy rozproszone. Zintegrowane systemy współpracy (inaczej produkcja lub produkcja) to coś, co musiałem uznać za własną architekturę, ponieważ jako pierwszy piszę kod w ten sposób.

Niektórzy uważają DTO za anemiczny model domeny, co oznacza, że ​​brakuje mu funkcjonalności, ale zakłada to, że obiekt musi posiadać dane, z którymi wchodzi w interakcje. Ten model koncepcyjny wymusza następnie dostarczanie danych między obiektami, który jest modelem przetwarzania rozproszonego. Jednak na linii produkcyjnej każdy krok może uzyskać dostęp do produktu końcowego i zmienić go bez jego posiadania lub kontroli. To jest różnica między przetwarzaniem rozproszonym i zintegrowanym. Produkcja oddziela produkt od operacji i logistyki.

Nie ma z natury nic złego w modelowaniu przetwarzania jako grupa bezużytecznych pracowników biurowych, którzy przesyłają sobie wiadomości e-mail bez prowadzenia śladu e-mail, z wyjątkiem całej dodatkowej pracy i problemów związanych z logistyką i problemami ze zwrotem. Prawidłowo modelowany rozproszony proces dołącza dokument (aktywny routing) do produktu opisujący operacje, z których pochodzi i do których ma przejść. Aktywny routing jest kopią routingu źródła procesu, która jest zapisywana przed rozpoczęciem procesu. W przypadku usterki lub innej zmiany awaryjnej aktywny routing jest modyfikowany w celu uwzględnienia kroków operacji, do których zostanie wysłany. To następnie odpowiada za całą pracę, która trafiła do produkcji.

RBJ
źródło