DTO = ViewModel?

103

Używam NHibernate do utrwalania obiektów mojej domeny. Aby zachować prostotę, używam projektu ASP.NET MVC jako warstwy prezentacji i warstwy usług.

Chcę zwrócić obiekty domeny w formacie XML z moich klas kontrolerów. Po przeczytaniu kilku postów tutaj w Stack Overflow, doszedłem do wniosku, że DTO jest drogą do zrobienia. Jednak natknąłem się również na posty mówiące o ViewModel.

Moje pytanie: czy obiekty transferu danych i modele widoków to to samo? A może ViewModel jest rodzajem podrzędnego wzorca DTO?

autonomatt
źródło
9
Myślę, że warto wspomnieć, że ViewModels w ASP.NET MVC nie są w 100% równoważne ViewModels w WPF (MVVM), ponieważ większość odpowiedzi wspomina o MVVM i pracujesz z ASP.NET MVC.
Matthijs Wessels

Odpowiedzi:

106

Kanoniczna definicja DTO to kształt danych obiektu bez żadnego zachowania.

ViewModels to model widoku. ViewModels zazwyczaj są pełnymi lub częściowymi danymi z jednego lub większej liczby obiektów (lub DTO) oraz wszelkich dodatkowych elementów członkowskich specyficznych dla zachowania widoku (metody, które mogą być wykonywane przez widok, właściwości wskazujące sposób przełączania elementów widoku itp.). Możesz spojrzeć na model widoku jako wszystkie dane dla widoku plus zachowania. ViewModels mogą, ale nie muszą, mapować jeden do jednego na obiekty biznesowe lub DTO.

Nawiasem mówiąc, projekcje NHibernate przydają się, jeśli określony model widoku potrzebuje podzbioru danych z utrwalonego obiektu.

Daniel Auger
źródło
Czy możesz to wyjaśnić: „DTO to kształt danych obiektu bez żadnego zachowania”?
roozbeh S
2
Czyli ... klasa DTO zwykle zawiera tylko właściwości i nie zawiera żadnych metod z logiką biznesową itp ...
Daniel Auger
71

ViewModel w praktyce ASP.NET MVC jest taka sama jak DTO, jednak ViewModel we wzorcu MVVM różni się od DTO, ponieważ ViewModel w MVVM ma zachowania, ale DTO nie ma.

Promień
źródło
4
To miła odpowiedź; aczkolwiek brakuje szczegółów.
Phil
5
Dlaczego ViewModel w asp.net mvc powinien być taki sam jak DTO? To nie ma sensu. ViewModel może mieć zachowanie, którego nie DTO. To nie zależy od mvc.
Elisabeth,
8
+1 do rozróżnienia między ASP.NET MVC ViewModel i MVVM ViewModel.
Ronald,
5
@Elisa - odpowiedzią na twoje raczej stare pytanie jest to, że w ASP.NET MVC widok wywołuje akcje na kontrolerze (a nie ViewModel) w celu zmiany modelu i widoku w sposób bezstanowy. Z tego powodu DTO ukształtowany do widoku jest zasadniczo taki sam jak ViewModel. Jednak w większych systemach z inną granicą serializacji DTO może być korzystne, jeśli jest oddzielone od ViewModel specjalnie ukształtowanego dla widoku.
dansan
27

DTO! = ViewModel

We wzorcu MVVM ViewModel służy do izolowania modelu z widoku. Do reprezentacji Modelu można użyć prostych klas DTO , które są ponownie mapowane do bazy danych przez np. NHibernate. Ale nigdy nie widziałem klasy ViewModel, która jest modelowana jako DTO .. ​​Klasy ViewModel w większości mają zachowanie, którego nie mają DTO.

stiank81
źródło
2
więc DTO może być po prostu strukturą (czy też klasą, która powinna naśladować możliwości struktury)?
Max Alexander,
20

DTO - Data Transfer Objects są dokładnie tak, jak mówi, kontenerami do przesyłania danych. Nie zachowują się, a jedynie gromada seterów i getterów. Niektórzy ludzie czynią je niezmiennymi i po prostu tworzą nowe w razie potrzeby, zamiast aktualizować istniejące. Powinny być możliwe do serializacji, aby umożliwić transfer przez kabel.

Ogólnie rzecz biorąc, DTO są używane do przesyłania danych z jednej warstwy do drugiej między granicami procesu, ponieważ wywołania zdalnej usługi mogą być kosztowne, więc wszystkie wymagane dane są wypychane do DTO i przesyłane do klienta w jednej porcji (gruboziarnistej).

Jednak niektórzy ludzie używają pojęcia DTO powiązanych z ekranem (nie ma to nic wspólnego z przekraczaniem granic procesu). Ponownie są one wypełniane wymaganymi danymi (zazwyczaj danymi wymaganymi dla określonego ekranu i mogą być agregacją danych z różnych źródeł) i wysyłane do klienta.

http://blog.jpboodhoo.com/CommentView,guid,21fe23e7-e42c-48d8-8871-86e65bcc9a50.aspx

W prostych przypadkach, jak już zostało powiedziane, ten DTO może być użyty do powiązania z widokiem, ale w bardziej złożonych przypadkach wymagałoby to utworzenia ViewModel i wyładowania danych z DTO do ViewModel, co jest oczywiście bardziej pracochłonne (przy zastosowaniu wzorca MVVM) .

Więc znowu, jak już wspomniano, DTO! = ViewModel

i

DTO i ViewModel mają różne cele w życiu

David
źródło
13

Po pierwsze, główna różnica polega na tym, że ViewModel może mieć zachowanie lub metody, których DTO nie może !!!

Po drugie, użycie DTO jako ViewModel w ASP.NET MVC sprawia, że ​​aplikacja jest ściśle powiązana z DTO, a to jest dokładnie odwrotnym celem korzystania z DTO. Jeśli to zrobisz, jaka jest różnica w używaniu modelu domeny lub DTO, większa złożoność uzyskania anty-wzorca?

Również ViewModel w ASP.NET może używać DataAnnotations do walidacji.

To samo DTO może mieć różne mapowanie modeli widoków, a jeden model widoku może składać się z różnych DTO (zawsze z mapowaniem obiektów, a nie kompozycją). ponieważ myślę, że jest jeszcze gorzej, jeśli masz ViewModel, który zawiera DTO, będziemy mieli ten sam problem.

Z warstwy prezentacji pomyśl o DTO jak o umowie, otrzymasz obiekt, który musisz uznać za obcy dla swojej aplikacji i nie masz nad nim żadnej kontroli (nawet jeśli masz ex the service, warstwy DTO i prezentacji są Twoje).

Wreszcie, jeśli wykonasz tę czystą separację, programiści mogą z łatwością współpracować. Osoba, która projektuje ViewModels, widoki i kontrolery, nie musi martwić się o warstwę usług lub implementację DTO, ponieważ wykona mapowanie, gdy inni programiści zakończą implementację ... Może nawet użyć narzędzia Mocking lub ręcznego mockowania do wypełnienia warstwa prezentacji z danymi do testu.

riadh gomri
źródło
1
Właśnie zainstalowałem VS 2012 i przyjrzałem się tam aplikacji jednostronicowej MVC 4. W przykładowym projekcie DTO są używane jako parametry metod kontrolera (lub akcji) w WebApi. Innymi słowy, JSON jest wysyłany do tych metod, a przy pewnej magii MVC dane są automatycznie konwertowane na DTO przed przekazaniem do metod. Czy uważasz, że używanie DTO w tym przypadku jest niewłaściwe. Czy ViewModels należy używać z interfejsem API sieci Web? Proszę o lepsze zrozumienie, ponieważ nadal nie jestem do końca zaznajomiony z tymi pojęciami.
Jean-François Beauchamp,
Salut Jean-François Beauchamp :) ASP.NET MVC może analizować wózki url do obiektu, na przykład: załóżmy, że mam to mapowanie na metodę index / index / {jobID} / {ResultsToSkip} / {ResultsToSend} "zamiast w Controlle Index (int jobID, int ResultsToSkip, int ResultsToSend) Będę miał Index (request) (request to obiekt, który zawiera 3 pola jobID ...) Więc teraz zamiast parametrów rozmawiasz z aplikacją za pomocą obiektów, które hermetyzują DANYCH, tak więc możemy powiedzieć requestDTO na przykład trzeba dodać jeszcze jedno pole tylko zmienić dto, a nie metody interfejsu API..
Riadh gomri
9

W przypadku niektórych prostych widoków użyję mojego DTO jako modeli, ale gdy widoki staną się bardziej złożone, utworzę ViewModels.

Dla mnie to równowaga pomiędzy szybkością (używanie DTO, bo już je mam) a elastycznością (tworzenie ViewModels oznacza większe rozdzielenie obaw).

sgwill
źródło
2
Niezła, pragmatyczna odpowiedź.
Simon Tewsi,
0

Jeśli użyjesz DTO jako ViewModel, oznacza to, że uzależniasz się od DTO z jakiegoś powodu, dla którego zmieniasz DTO, może to mieć wpływ na ViewModel.

Lepiej używaj DTO i konwertuj na model widoku.

Lalit Khanna
źródło
-1

Możemy użyć tego DTOsamego co klasa Model i możemy użyć viewmodel, gdy potrzebujemy pokazać / użyć danych / właściwości wielu modeli w jednym widoku. Przykład: Najpierw tworzę model, używając bazy danych platformy encji. Więc teraz cały model generuje się na podstawie bazy danych. a teraz potrzebujemy adnotacji danych, dla tych adnotacji danych możemy utworzyć nazwę folderu DTO, W tym folderze DTO możemy zachować dokładność wszystkich modeli, które już generują i dodają adnotację danych nad właściwością. Następnie możemy użyć dowolnej operacji (użyj kontrolera, widoków) używając tych klas DTO. A kiedy potrzebujemy złożonego widoku, mam na myśli, że potrzebujemy danych wielu klas w jednym widoku, możemy użyć viewmodel. W przypadku viewmodel możemy utworzyć nazwę folderu viewmodel, a następnie utworzyć klasę niestandardową i zachować tę właściwość, której potrzebujemy. Próbowałem się oczyścić. Każda sugestia jest wysoko ceniona.

Md. Saddam Hossain
źródło