DTO = ViewModel?

103

Я использую NHibernate для сохранения объектов моего домена. Для простоты я использую проект ASP.NET MVC как в качестве уровня представления, так и в качестве уровня обслуживания.

Я хочу вернуть свои объекты домена в XML из моих классов контроллера. Прочитав несколько сообщений здесь, в Stack Overflow, я понял, что DTO - это правильный путь. Однако я также встречал сообщения о ViewModel.

Мой вопрос: объекты передачи данных и модели представления - одно и то же? Или ViewModel - это своего рода подшаблон DTO?

автономный
источник
9
Я думаю, уместно упомянуть, что ViewModels в ASP.NET MVC не на 100% эквивалентен ViewModels в WPF (MVVM), поскольку в большинстве ответов упоминается MVVM, и вы работаете с ASP.NET MVC.
Matthijs Wessels

Ответы:

106

Каноническое определение DTO - это форма данных объекта без какого-либо поведения.

ViewModels - это модель представления. ViewModels обычно представляют собой полные или частичные данные из одного или нескольких объектов (или DTO) плюс любые дополнительные члены, специфичные для поведения представления (методы, которые могут быть выполнены представлением, свойства, чтобы указать, как переключать элементы представления и т. Д.). Вы можете рассматривать модель представления как все данные для представления плюс поведение. ViewModels может или не может отображать один в один для бизнес-объектов или DTO.

Кстати, проекции NHibernate пригодятся, если для определенной модели представления требуется подмножество данных из постоянного объекта.

Даниэль Аугер
источник
Можете ли вы объяснить это: «DTO - это форма данных объекта без какого-либо поведения»?
roozbeh S
2
Это означает ... класс DTO обычно содержит только свойства и не содержит никаких методов с бизнес-логикой и т. Д.
Дэниел Аугер,
71

ViewModel в практике ASP.NET MVC совпадает с DTO, однако ViewModel в шаблоне MVVM отличается от DTO, поскольку ViewModel в MVVM имеет поведение, а DTO - нет.

Луч
источник
4
Это хороший ответ; хотя и кратко по деталям.
Фил
5
Почему ViewModel в asp.net mvc должен быть таким же, как DTO? Это не имеет смысла. ViewModel может иметь поведение, которого нет в DTO. Это не зависит от mvc.
Элизабет
8
+1 для различения между ASP.NET MVC ViewModel и MVVM ViewModel.
Рональд
5
@Elisa - Ответ на ваш довольно старый вопрос заключается в том, что в ASP.NET MVC представление вызывает действия на контроллере (а не ViewModel) для изменения модели и представления без сохранения состояния. Из-за этого DTO, сформированный в виде представления, по сути такой же, как ViewModel. Однако в более крупных системах с другой границей сериализации DTO может быть полезным, если он отделен от ViewModel, специально сформированного для View.
dansan
27

DTO! = ViewModel

В шаблоне MVVM ViewModel используется для изоляции модели от представления. Для представления модели вы можете использовать простые классы DTO , которые снова отображаются в базе данных, например, с помощью NHibernate. Но я никогда не видел класса ViewModel, который моделируется как DTO. Классы ViewModel в основном имеют поведение, которого нет у DTO.

stiank81
источник
2
так что DTO могут быть просто структурами (или классом, который должен имитировать возможности структуры)?
Max Alexander
20

DTO - Data Transfer Objects - это, как говорится, контейнеры для передачи данных. У них нет поведения, а есть просто группа сеттеров и геттеров. Некоторые люди делают их неизменяемыми и при необходимости просто создают новые, а не обновляют существующие. Они должны быть сериализуемыми, чтобы разрешить передачу по сети.

Обычно DTO используются для передачи данных с одного уровня на другой через границы процесса, поскольку вызовы удаленной службы могут быть дорогостоящими, поэтому все необходимые данные помещаются в DTO и передаются клиенту одним фрагментом (крупнозернистым).

Однако некоторые люди используют понятие DTO, привязанного к экрану (ничего общего с пересечением границ процесса). Они снова заполняются необходимыми данными (обычно данными, необходимыми для определенного экрана и могут быть агрегированием данных из различных источников) и отправляются клиенту.

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

В простых случаях, как уже было сказано, этот DTO можно использовать для привязки к представлению, но в более сложных случаях потребуется создание ViewModel и выгрузка данных из DTO в ViewModel, что, очевидно, требует больше работы (при применении шаблона MVVM) .

Итак, как уже было сказано, DTO! = ViewModel

и

DTO и ViewModel имеют разные цели в жизни

Дэвид
источник
13

Во-первых, основное отличие состоит в том, что ViewModel может иметь поведение или методы, которые DTO не должны !!!

Во-вторых, использование DTO в качестве ViewModel в ASP.NET MVC делает ваше приложение тесно связанным с DTO, а это прямо противоположная цель использования DTO. Если вы это сделаете, какая разница при использовании вашей модели домена или DTO, сложнее получить анти-шаблон?

Также ViewModel в ASP.NET может использовать DataAnnotations для проверки.

Один и тот же DTO может иметь разные сопоставления ViewModels, и одна ViewModel может быть составлена ​​из разных DTO (всегда с сопоставлением объектов, а не композицией). потому что я думаю, что будет еще хуже, если у вас есть ViewModel, содержащий DTO, у нас будет та же проблема.

На уровне представления подумайте о DTO как о контракте, вы получите объект, который вы должны рассматривать как незнакомый для вашего приложения и не имеющий никакого контроля над ним (даже если у вас есть служба, уровни dto и презентации ваши).

Наконец, если вы сделаете это четкое разделение, разработчики смогут легко работать вместе. Человеку, который разрабатывает модели представления, представления и контроллеры, не нужно беспокоиться об уровне обслуживания или реализации DTO, потому что он сделает сопоставление, когда другие разработчики завершат свою реализацию ... Он даже может использовать инструмент Mocking или ручное издевательство для заполнения слой представления с данными для тестирования.

Риад Гомри
источник
1
Я только что установил VS 2012 и посмотрел на одностраничное приложение MVC 4. В примере проекта DTO используются в качестве параметров для методов (или действий) контроллера в WebApi. Другими словами, JSON отправляется этим методам, и с некоторой магией MVC данные автоматически преобразуются в DTO перед передачей в методы. Считаете ли вы, что в этом случае неправильно использовать DTO? Следует ли использовать модели ViewModels с веб-API? Я прошу лучше понять, потому что я еще не совсем знаком с этими концепциями.
Жан-Франсуа Бошан
Салют, Жан-Франсуа Бошан :) ASP.NET MVC может анализировать URL-адреса детских колясок в объект, например: предположим, что у меня есть это сопоставление с методом индекса ajax / index / {jobID} / {ResultsToSkip} / {ResultsToSend} "вместо того, чтобы иметь в элементе управления Index (int jobID, int ResultsToSkip, int ResultsToSend) у меня будет Index (запрос) (запрос - это объект, который инкапсулирует 3 поля jobID ...) Итак, теперь вместо params вы разговариваете со своим приложением с объектами, которые инкапсулируют ДАННЫЕ, так что да, мы можем сказать requestDTO. Например, вам нужно добавить еще одно поле, вы меняете только DTO, а не методы интерфейса api.
riadh gomri 08
9

Для некоторых простых представлений я буду использовать DTO в качестве моделей, но по мере того, как представления станут более сложными, я создам модели представления.

Для меня это баланс между быстротой (с использованием DTO, поскольку они у меня уже есть) и гибкостью (создание ViewModels означает большее разделение проблем).

sgwill
источник
2
Хороший прагматичный ответ.
Саймон Тевси
0

Если вы будете использовать DTO как ViewModel, это означает, что вы сильно зависим от DTO из-за того, что по какой-то причине вы меняете DTO, тогда это может повлиять на ViewModel.

Лучше использовать DTO и преобразовать в модель просмотра.

Лалит Ханна
источник
-1

Мы можем использовать DTOТо же, что и класс Model, и мы можем использовать модель просмотра, когда нам нужно показать / использовать данные / свойство нескольких моделей в одном представлении. Пример: сначала я создаю некоторую модель, используя базу данных Entity Framework. Итак, теперь вся модель генерируется на основе базы данных. и теперь нам нужна аннотация данных, для этой аннотации данных мы можем создать папку с именем DTO. В этой папке DTO мы можем сохранить все модели в точности, которые уже генерируют, и добавить аннотацию данных над свойством. Затем мы можем использовать любую операцию (использовать контроллер, представления), используя эти классы DTO. И когда нам нужно сложное представление, я имею в виду, когда нам нужны данные нескольких классов в одном представлении, мы можем использовать модель представления. Для модели просмотра мы можем создать имя папки viewmodel, а затем создать собственный класс и сохранить это свойство, которое нам нужно. Я попытался очиститься. Любое предложение высоко ценится.

Md. Саддам Хоссейн
источник