Является ли текущая модель представления MVVM нарушением принципа единой ответственности? - PullRequest
19 голосов
/ 23 августа 2011

С текущими практиками (по крайней мере, с WPF и Silverlight) мы видим представления, связанные через привязки команд в модели представления, или мы по крайней мере видим события представления, обрабатываемые в моделях представления. Это выглядит как нарушение SRP , потому что модель представления не просто моделирует состояние представления, но отвечает представлению (пользователю). Другие спрашивали , как строить модели представления, не нарушая SRP , или , делают ли их реализации (это последний контроллер в MVC, но примерно аналогичный).

Так что нынешняя практика является нарушением ПСП? Или «модель представления» действительно представляет собой набор вещей, которые не нарушают SRP? Чтобы сформулировать это немного, нам кажется, что нам нужно знать, что является единственной ответственностью или если в концепции 1010 * есть несколько обязанностей, то разделены ли индивидуальные обязанности в соответствии с ПСП. Я не уверен.

Определение Википедии модели представления гласит

[T] Модель ViewModel - это «Модель представления», то есть абстракция представления, которая также служит для привязки данных между представлением и моделью.

Это кажется достаточно хорошим для SRP, но затем в записи говорится (мой акцент добавлен)

[ViewModel] действует как механизм связывания / преобразования данных, который изменяет информацию о модели на информацию о представлении и передает команды из представления в модель

В блоге Prism о роли модели представления автор говорит (снова мой акцент)

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

  • абстракция вида
  • команда
  • преобразователи значений
  • просмотр состояния

Я уверен, что пропустил много определений, но они, кажется, попадают в следующие категории:

  1. Единая «расплывчатая» ответственность за моделирование состояния представления (так что же нам делать?) означает по состоянию)
  2. Множество обязанностей (просмотр состояния, взаимодействие с пользователем (т.е. команды)) * * 1 056
  3. Сочетание отдельных конкретных обязанностей (абстракция, состояние, взаимодействие, преобразование), таким образом, имея единый ответственность: «управлять всем этим».

Если вам любопытно, я «забочусь» об этом, потому что (2) чувствует себя хорошо, но кажется противоречащим преобладающим реализациям.

Ответы [ 4 ]

10 голосов
/ 23 августа 2011

Одиночная ответственность как Мартин определяет ее :

"НИКОГДА НЕ ДОЛЖНО БЫТЬ БОЛЬШЕ, ЧЕМ ОДНА ПРИЧИНА КЛАССА ДЛЯ ИЗМЕНЕНИЯ."

Модель представления, с точки зрения MVVM, на самом деле является просто специализированной реализацией презентационной модели .

Таким образом, хотя можно утверждать, что Модель представления должна представлять только состояние пользовательского интерфейса, а Presenter / Controller всегда должен быть посредником Команды между пользовательским интерфейсом и моделью представления. Если следовать этой идее, когда SRP делится на State и Commands , то добавление команды не должно влиять на класс, представляющий состояние. Поэтому MVVM сломает SRP.

Однако ...

Я думаю, что это цепляется за соломинку. MVVM - это довольно специализированная реализация, используемая в основном в WPF / Silverlight ( и теперь браузерные клиенты ).

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

6 голосов
/ 24 августа 2011

Я считаю, что многие из современных практик, связанных с MVVM, нарушают SPR (по крайней мере).Это еще одна ситуация, когда простое добавление контроллеров обратно в MVVM решит все проблемы без проблем.Я называю это MVCVM:)

Шаблон, который мы успешно используем во всех недавних проектах, заключается в регистрации контроллеров only в модулях и их инициализации при запуске.Контроллеры очень легкие / тонкие, и единственное, что нужно для работы приложения , для прослушивания или отправки сообщений .В своих методах инициализации они затем регистрируют все, что им нужно (представления и модели представления и т. Д.).Этот легкий шаблон логики «только в памяти» также подходит для более тонких приложений (например, лучше для WP7).

Проблема с использованием виртуальных машин, как вы обнаружили, заключается в том, что в конечном итоге вы сталкиваетесь с ситуациями, когда им необходимознать о представлениях, или командах, или других вещах, с которыми не должен быть связан уважающий себя ViewModel!

Основные правила, которым мы следуем:

  • Контроллеры принимают решения на основе событий
  • Контроллеры извлекают данные и помещают их в соответствующие свойства модели представления
  • Контроллеры устанавливают свойства ICommand моделей представления для перехвата событий
  • Контроллеры позволяют отображать представления (если это не указано в другом месте)
  • Просмотр моделей "тупой".Удерживаемые данные для привязки и ничто иначе
  • Представления знают, что они отображают определенную форму данных, но не имеют представления, откуда они берутся

Последние дваТочки - это те, которые вы никогда не должны нарушать, или разделение интересов выходит из окна.

Простое добавление контроллеров обратно в смесь MVVM, кажется, решает все проблемы, которые мы обнаружили.MVVM это хорошо, но почему они не включают контроллеры?( но это, конечно, только мое мнение ):)

6 голосов
/ 24 августа 2011

Нет!MVVM не нарушает SRP, (программист делает, lol!)

Нет причин, по которым при использовании шаблона MVVM необходимо игнорировать SRP.MVVM не означает, что существует только один класс модели, один класс модели представления и один класс представления.Конечно, если бы у вас был только один класс View, вы могли бы показать только один простой экран.

Те классы, которые находятся на уровне View, должны отвечать за одну вещь;делать, решать или содержать.Представление может состоять из нескольких вложенных представлений, чья работа состоит в том, чтобы выполнять определенные части взаимодействия пользователей.Рассмотрим базовую форму, она имеет сетку отображения, элементы в сетке можно редактировать, а также есть кнопка «Сохранить».

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

Таким образом, представление редактирования (используется DataGrid).является агностиком в отношении того, что его использует, и несет одну ответственность;То же самое с командным управлением.Аналогично, DataGrid не заботится о том, кто его использует, а только то, что он может содержать представление редактирования (дочерний).Хороший SRP там.

ViewModels, чтобы соответствовать представлениям (и дочерним элементам), также ответственны за одну вещь.Edit View Model - это контейнер, к которому привязывается Edit View;он просто содержит поля данных, которые можно отображать / редактировать.Он не заботится ни о чем, кроме как сигнализировать об изменении одного из его свойств.Модель Представления Командной кнопки - класс, который делает вещи.Его команды привязаны к кнопкам, и он будет работать в зависимости от того, на что нажимает пользователь.Для работы он должен иметь доступ к другим частям ViewModel (ов).

На главной странице View Model есть другие дочерние представления.Он несет полную ответственность за инициализацию, создание всех необходимых экземпляров ViewModel и передачу параметров конструктора другим экземплярам ViewModel (скажем, модели представления Command Button, чтобы он знал, где получить данные для своей работы)

Это естественновтиснуть целую кучу функций в одну ViewModel, к которой привязан большой View.Но это не должно быть так, и SRP может поддерживаться в MVVM.

Основная цель MVVM - обеспечить тестируемый дизайн, уровень модели можно тестировать независимо, все классы в моделиможет легко следовать SRP.ViewModel может быть протестирована без необходимости просмотра;становится сложнее думать о SRP во ViewModel, но это, безусловно, выполнимо;просто не забывайте устраивать уроки, чтобы у них была только одна проблема.Представление обязательно должно быть разделено на ViewModels. Если вам повезет, то тестирование модели ViewModel сделает привязку представлений очень простой.Помните, что вы можете позволить каждому View-let придерживаться SRP быть частью более крупного конгломерата View (контейнер).

TL; DR?Чтобы ответить на ваш вопрос напрямую, View - это набор классов, который не нарушает SRP.Таким образом, когда ViewModel абстрагируется от View (s) (View-First), они также представляют собой набор классов, которые придерживаются хорошего SRP.

2 голосов
/ 23 августа 2011

Что сводится к тому, что модель представления является составной из следующего:

  • абстракция представления
  • команды
  • значениеконвертеры
  • состояние просмотра

Не понимаю, почему вы разделили первые два элемента.Команды являются частью представления.

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

Так?

...