Почему два класса, модель модели и домена?

Я знаю, что может быть плохо использовать модели домена в качестве моделей просмотра. Если у моей модели домена есть свойство с именем IsAdmin, и у меня есть действие контроллера Create для создания пользователей, кто-то может изменить мою форму и получить ее для POST значения IsAdmin = true, даже если бы я не раскрывал такое текстовое поле в моем представлении, Если я использую привязку модели, тогда, когда я передал свою модель домена, этот человек теперь будет администратором. Таким образом, решение становится разоблачением только тех свойств, которые мне нужны в модели представления, и с помощью инструмента, такого как AutoMapper, для сопоставления значений свойств моего объекта модели объекта возврата с объектом моего объекта модели домена. Но я читал, что атрибут bind в классе может использоваться для указания привязки модели, какие свойства он должен и не должен связывать. Итак, что на самом деле является причиной того, что два отдельных класса (модель домена и модель представления) являются существенными, представляют собой одно и то же, а затем накладывают накладные расходы при их сопоставлении? Является ли это скорее проблемой организации кода, и если да, то как мне приносить пользу?

ИЗМЕНИТЬ

Одна из самых важных причин, по которой я столкнулся с моделью просмотра, которая отличается от модели домена, - это необходимость реализации шаблона MVVM (на основе шаблона PM Мартина Фаулера) для управления сложными пользовательскими интерфейсами.

Ответ 1

Я обнаружил, что, хотя моя модель домена получает мне 85% от того, как мне нужны поля, она никогда не покрывала 100% значений, которые я хочу на моем представлении. Особенно, когда речь идет о разрешениях и должен ли пользователь иметь доступ к определенным частям представления.

Концепция дизайна, которую я пытаюсь выполнить, состоит в том, чтобы иметь как можно меньше логики в моих представлениях. Это означает, что у меня есть поля в моей модели, например "CanViewThisField" или "CanEditThisField". Когда я впервые начал работать с MVC, я бы использовал модель моего домена в качестве модели моего представления, и я всегда сталкивался с сценарием, где мне требовалось только одно или два поля, чтобы сделать мой взгляд менее загроможденным. С тех пор я пропустил маршрут View Model/Model Builder, и он отлично работал у меня. Я больше не сражаюсь с моим кодом, но могу улучшить мою модель представления, поскольку мне нужно, не затрагивая модель домена.

Ответ 2

Еще одна веская причина иметь ViewModel - подкачки больших наборов данных. Вы можете передать представление массиву Person (Person[]), но метаданные, такие как количество страниц, номер текущей страницы, размер страницы не будут принадлежать классу Person.

Поэтому PersonListViewModel решит эту проблему.

Ответ 3

Иногда вам нужно отображать данные определенным образом (т.е. отображать дату в формате mm/dd/yyyy против yyyy/mm/dd), и часто легче сделать это свойство в представлении, а не в модели домена, где вы должны (или должны) иметь сопоставление с столбцом в вашем db.

Ответ 4

ViewModel содержит только те элементы, которые требуются для представления. Их обычно можно рассматривать как упрощение или "сглаживание" базовой модели домена.

Думайте о них вот так:

  • ViewModel: это данные, которые подходят для рендеринга на этом вид
  • Модель домена: это вся информация, которую мне требуется приложение об этом объекте для выполнения всех его функций.

Например, мой класс Order имеет член Customer, который является composition, то есть мой заказ имеет Клиента. Этот объект Customer имеет такие элементы, как First Name, Lastname и т.д. Но как я могу показать это на "подробном" представлении заказа или в списке Заказов и Клиентов, которые их разместили?

Ну, используя ViewModel, у меня может быть OrderListItemViewModel, у которого есть член CustomerName, и я могу сопоставить комбинацию Firstname и Lastname от объекта Customer к этому. Это можно сделать вручную или, желательно, с помощью Automapper или аналогичного.

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

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

Ответ 5

вам нужно помнить что ваш domain model classes используется только internally; то есть они никогда не отправляются на клиент. Это то, к чему используются типы вашей модели обслуживания (View Model types) - они представляют данные, которые будут перемещаться между клиентом и вашей службой.