Это хорошая идея, чтобы добавить ViewModel точно так же, как модель

16

У меня есть следующие слои в моем решении:

  1. App.Domain
  2. App.Service
  3. App.Core (возможно, вы называете это App.DataLayer)
  4. App.Web

Шаблон проектирования программного обеспечения не мой вопрос, у меня есть следующая модель в Domain

public class Foo {
    public int Id {get;set;}
    public int Name {get;set;}
    public int Value {get;set;}
}

Я хочу использовать эту модель в представлении (например, на домашней странице) И я хочу использовать Id, Name & Value, поэтому, если я хочу создать ViewModel, я добавлю следующее:

public class FooViewModel {
    public int Id {get;set;}
    public int Name {get;set;}
    public int Value {get;set;}
}

Так это хорошая идея? или просто использовать Fooвместо FooViewModel?

Мехди Дехгани
источник
Я не уверен, что понимаю это. Разве Modelобычно не передается View? Почему именно вам нужно воссоздать поля Modelв View? Если целью является разделение интересов MVC, при каких обстоятельствах можно сделать то же самое с Modelи View? Если ViewModelесть и то и другое, то почему бы не расширять / составлять оба Modelи View?
ноль
пожалуйста, прочитайте мои комментарии к ответу @ svidgen
Мехди Дехани
У меня есть проблема, связанная с тем, что валидация (обязательный атрибут) в моделях (и в базе данных) указывает, что определенные значения должны быть введены, но в представлениях эти значения не нужны, поэтому я вынужден скопировать некоторые поля из модели внутри модели представления, а не ссылки на модель напрямую. Однако, если подумать, это, вероятно, хорошо и действительно не нарушает DRY, поскольку они предназначены для разных целей (в любом случае, не так уж и плохо).
niico

Ответы:

20

На первый взгляд это может выглядеть как нарушение правила DRY, но я бы сказал, что «похожий и даже идентичный код» не обязательно «повторяется», если он делает что-то другое или может измениться независимо. А в случае моделей представлений код определяет то, что видит «клиент», а не обязательно объекты и операции, о которых говорит бизнес. Таким образом, вы часто показываете клиенту или интерфейсу модели, которые являются «случайно идентичными». Вы можете изменять бизнес-правила и условия или терминологию конечного пользователя независимо друг от друга.

Итак, я бы перевернул вопрос обратно на вас. Если домен изменяется, допустимо ли для клиентов «версии 1» продолжать использовать старые интерфейсы? Будете ли вы когда-нибудь раскрывать термины или операции в интерфейсе, которые не являются частью "основных бизнес-правил"? И наоборот?

Подобные вопросы в виду, если «функция» вашего взгляда состоит в том, чтобы строго раскрыть модель предметной области, да, похоже, что это нарушает правило СУХОЙ.

Также имейте в виду, что представление некоторых более естественных изменений с изменениями модели также может быть достигнуто в некоторых языках с атрибутами и отражением элемента. (Или с меньшим количеством повторений через другие умные умения ... Но «умный ум» часто не оправдывает повторение, которое вас щадит.)

svidgen
источник
Хорошие упомянутые заметки (проголосуйте за это), как я уже сказал в качестве комментария к предыдущему ответу, я говорю об общем назначении изображений, возможно, через несколько дней я решил добавить новое поле / свойство Foo, поэтому, если я использовал его Fooкак ViewModel Кроме того, клиент также получит новое свойство, так что если я должен сделать это новое поле безопасности (может быть true / false для разрешения или что-то в этом роде), что мне делать?
Мехди Дегхани
@mehdi, вам нужно будет более конкретно указать, какую область вы хотите добавить и почему вы думаете, что она принадлежит или не относится к представлению. Или вообще, какая тут проблема.
svidgen
@ mehdi, чтобы быть понятным, если вы беспокоитесь о том, что конечные пользователи изменяют значение безопасности, ваш домен просто не должен позволять пользователям сохранять вещи, на которые они не авторизованы
svidgen
Почему мы используем ViewModels? Есть некоторые причины, как мы знаем, одна из них User edit formсвязана с безопасностью, например, в том , что нам не нужно передавать IsAdminполе клиенту, чтобы сохранить это поле в безопасности, поэтому я беспокоюсь об этом. Извините за мой плохой английский.
Мехди Дехгани
1
Другими словами, я думаю, что оригинальный вопрос - это полный вопрос. Вопрос, который вы пытаетесь выяснить в комментариях, это еще один полный вопрос. И комментарии не являются хорошим способом получить хорошие, качественные ответы.
svidgen
2

Я хотел бы иметь модель представления, которая содержала бы только одно свойство, экземпляр Foo. Таким образом, вы не нарушаете DRY согласно какому-либо определению, если Foo изменяется, ваша модель представления автоматически видит изменение, и вы освобождаете себя от прямой связи модели представления с моделью.

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

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

Не уверен, что я объяснил это ясно. Если нет, дайте мне знать, и я постараюсь перефразировать его, когда я не сплю!

Аврохом Исроэль
источник
-2

Я бы сказал, что использование FooViewModelтаким образом нарушает принцип DRY. Когда вам нужно внести изменения, Fooвы также должны внести изменения в FooViewModel. Я думаю, что вы бы лучше служили, просто используя Fooв качестве модели для вашего взгляда. Я хотел бы рассмотреть модель представления, если вам нужно отобразить вещи из Foo и что-то другое. Например, скажем, вам нужно визуализировать некоторую информацию из, Fooа также из Bar.

zero_dev
источник
Пожалуйста, скажите мне, если я решил добавить другое поле / свойство к Fooтак, потому что я Fooтоже использовал в качестве ViewModel, поэтому я должен передать это новое поле в представление, я думаю, что это не очень хорошая сделка, что вы думаете ?
Мехди Дехани
Я не вижу ничего плохого в том, что View использует только подмножество данных, представленных моделью. Я думаю, что большая фол это связь между Fooи FooViewModel. Как правило, не рекомендуется изменять несколько файлов для одного логического изменения.
zero_dev
Что делать, если это добавленное поле было полем безопасности, например, какое-то true/falseзначение для разрешения или что-то в этом роде.
Мехди Дехгани
Вам не нужно открывать такие поля в самом представлении, но вы все равно должны убедиться, что остальная часть вашего кода не позволяет пользователю изменять уровень безопасности, на случай, если злонамеренный пользователь попытается POST такое изменение.
Грэм
Похоже, что это будет открыто для массовых атак назначения
Джеймс