Подтвердить что ты не робот

Являются ли текущие модели поведения MVVM нарушением принципа единой ответственности?

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

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

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

[T] он ViewModel является "моделью представления", что означает абстракцию представления, которое также служит для связывания данных между представлением и моделью

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

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

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

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

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

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

  • Одиночная "неопределенная" ответственность за моделирование состояния представления (так что же мы делаем означает состояние)
  • Несколько обязанностей (состояние просмотра, взаимодействие с пользователем (т. команды))
  • Составные отдельные обязанности (абстракция, состояние, взаимодействие, преобразование), имея при этом одну Ответственность: "Управление всем этим".

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

4b9b3361

Ответ 1

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

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

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

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

Однако...

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

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

Ответ 2

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

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

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

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

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

ViewModels для соответствия Views (и дети) также несут ответственность за одну вещь. Модель "Редактировать вид" - это контейнер, к которому привязывается редактирование вида; он просто содержит поля данных, которые могут отображаться/редактироваться. Он не заботится ни о чем, кроме сигнализации, когда меняется одно из свойств. Модель Command Button View - это класс, который делает вещи. Эти команды привязаны к кнопкам, и они будут работать на основе того, на что пользователь нажимает. Он должен будет иметь доступ к другим частям ViewModel (ов), чтобы это работало.

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

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

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

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

Ответ 3

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

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

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

Ниже приведены основные правила:

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

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

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

Ответ 4

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

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

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

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

Так?