Зачем использовать MVVM?


хорошо, я изучал шаблон MVVM, и каждый раз, когда я ранее пытался его изучить, я сдался по ряду причин:

  1. Ненужные Удлиненные Наматывается Кодирования
  2. нет очевидных преимуществ для кодеров (нет дизайнеров в мой кабинет. В настоящее время только я скоро буду другим кодером)
  3. не так много ресурсов / документации о передовой практике! (Или, по крайней мере, трудно найти)
  4. не могу придумать ни одного сценария, где это выгодный.

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

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

может ли кто-нибудь показать пример того, где Использование шаблона MVVM сэкономит время по сравнению с XAML привязка данных.

100% мои привязки в XAML на данный момент. И поэтому я не вижу смысла в VM как его просто дополнительный код, который мне нужно написать и зависеть от него.

EDIT:
Проведя день, исследуя MVVM, я, наконец, нашел то, что заставило меня осознать истинные преимущества этого ответа.

13 65

13 ответов:

резюме

  • использование всех паттернов является ситуативным, и преимущество (если оно есть) всегда заключается в уменьшении сложности.
  • MVVM помогает нам распределять обязанности между классами в графическом приложении.
  • ViewModel проецирует данные из модели в формат, соответствующий представлению.
  • для тривиальных проектов MVVM не нужен. Достаточно использовать только вид.
  • для простых проектов Разделение ViewModel/Model может быть ненужным, и просто использование модели и представления достаточно хорошо.
  • модель и ViewModel не должны существовать с самого начала и могут быть введены, когда они необходимы.

когда использовать шаблоны и когда избегать их

для достаточно простого применения каждый шаблон дизайна является излишним. Предположим, вы пишете приложение GUI, которое отображает одну кнопку, которая при нажатии показывает "Hello world". В этом случае, дизайн такие шаблоны, как MVC, MVP, MVVM, добавляют много сложности, не добавляя при этом никакого значения.

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

чтобы объяснить знакомую и незнакомую сложность, возьмите следующие 2 последовательности символов:

  • " D.€ / Ré%dfà?с"
  • "CorrectHorseBatteryStaple"

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

имейте в виду, что некоторые шаблоны могут быть знакомы не всем разработчикам, которые собираются работать с кодом в будущем. С точки зрения предыдущего примера, следующая последовательность может быть или не быть легче запомнить, чем любая из последовательностей выше, в зависимости от опыта и подготовки человека, запомнившего ее: "3.14159265358979323846264338327950". В некоторых случаях, когда задействованы более продвинутые шаблоны проектирования, имеет смысл использовать только дизайн шаблон, если разработчики обслуживания уже знакомы с ним.

MVVM

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

'Proper' MVVM предполагает по крайней мере a умеренно сложное приложение, которое имеет дело с данными, которые он получает "откуда-то". Он может получить данные из базы данных, файла, веб-сервис, или из множества других источников.

пример

в нашем примере у нас есть 2 класса View и Model, а не ViewModel. Элемент Model обертывает csv-файл, который он читает при запуске и сохраняет, когда приложение завершает работу, со всеми изменениями, внесенными Пользователем в данные. Элемент View - Это класс окна, который отображает данные из элемент Model в таблице и позволяет пользователю редактировать данные. Содержимое csv может выглядеть примерно так:

ID, Name, Price
1, Stick, 5$
2, Big Box, 10$
3, Wheel, 20$
4, Bottle, 3$

новые требования: показать цену в евро

сейчас нас просят внести изменения в наше приложение. Данные состоят из 2-мерной сетки, которая уже имеет столбец "цена", содержащий цену в долларах США. Нам нужно добавить новый столбец, который показывает цены в евро в дополнение к тем, в долларах США, исходя из заданного курса. Формат csv-файла не должны меняться, потому что другие приложения работают с тем же файлом, и эти другие приложения не находятся под нашим контролем.

возможное решение-просто добавить новый столбец Model класса. Это не лучшее решение, потому что Model сохраняет все данные, которые он предоставляет в csv - и мы не хотим, чтобы новый столбец цены евро в csv. Так что изменение на Model было бы нетривиально, и было бы также сложнее описать, что делает класс модели, который является a код запах.

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

представляем ViewModel

нет ViewModel в приложении, потому что до сих пор Model представляет данные именно так, как это нужно Csv, что также является способом View в ней нуждается. Имея ViewModel между ними была бы добавлена сложность без цели. Но теперь, когда Model больше не представляет данные так, как View это нужно, мы пишем ViewModel. The ViewModel проецирует данные Model в таком так что View может быть простым. ранее View класс подписался на Model класса. Теперь новый ViewModel класс подписывается на Model класс, и разоблачает к View - С дополнительной колонкой, отображающей цену в евро. Элемент View не знает Model, теперь он знает только ViewModel, который с точки зрения View выглядит так же, как Model раньше - за исключением того, что открытые данные содержат только новая читать колонна.

новые требования: другой способ форматирования данных

следующий запрос клиента заключается в том, что мы не должны отображать данные в виде строк в таблице, а вместо этого отображать информацию о каждом элементе (a.k.a. row) в виде карты/коробки и отображать 20 ящиков на экране в сетке 4x5, показывая 20 ящиков за раз. Потому что мы сохранили логику View просто, мы просто заменяем View полностью с новым классом, который делает так, как хочет клиент. Конечно есть еще один клиент, который предпочел старый View, Так что теперь нам нужно поддерживать оба. Потому что вся общая бизнес-логика уже находится в ViewModel это не большая проблема. Поэтому мы можем решить эту проблему, переименовав класс View в TableView, и написание нового CardView класс, который показывает данные в формате карты. Нам также придется написать некоторый код клея, который может быть oneliner в функции запуска.

новые требования: динамический обмен размере

следующий запрос клиента заключается в том, что мы тянем курс из интернета, а не использовать предопределенный курс. Это тот момент, когда мы возвращаемся к моему предыдущему заявлению о "слоях". Мы не меняем наши Model класс для обеспечения обменного курса. Вместо этого мы пишем (или находим) полностью независимый дополнительный класс, который обеспечивает обменный курс. Этот новый класс становится частью слоя модели, а наш ViewModel консолидирует информацию о csv-модели и модель обменного курса, которую он затем представляет View. Для этого изменения старый класс модели и класс представления даже не должны быть затронуты. Ну, нам нужно переименовать класс модели в CsvModel и мы называем новый класс ExchangeRateModel.

если бы мы не представили ViewModel, когда мы это сделали, но вместо этого ждали до сих пор, чтобы сделать это, объем работы по внедрению ViewModel теперь был бы выше, потому что нам нужно удалить значительные объемы функциональности из оба из View и Model и переместите функциональность в ViewModel.

послесловие по модульным тестам

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

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

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

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

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

Это помогает вам отделить графический интерфейс и логику программы; смешивание их может привести к очень трудно поддерживать приложения, особенно когда ваш проект растет со временем.

с здесь:

Почему вы, как разработчик, даже забота о модель-представление-модель представления образец? Существует ряд преимущества эта картина приносит к обоим Разработка WPF и Silverlight. Прежде чем продолжить, спросите себя:

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

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

  • проще работать с дизайнерами (не программистами, а просто людьми, использующими Blend)
  • код для тестирования (unit-тесты)
  • гораздо проще изменить вид, не возясь с остальной частью кода
  • во время разработки пользовательского интерфейса вы можете макетировать модель и разрабатывать свой интерфейс без запуска реальной службы (просто используя макетные данные из модели). Затем вы просто переворачиваете флаг и подключаетесь к сервису.

есть много хороших вещей о MVVM, но, возможно, самое главное-это возможность проверить свой код (модульное тестирование ViewModels).

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

с статья Джоша Смита о MVVM:

В дополнение к WPF (и Silverlight 2) особенности, которые делают MVVM естественный способ структурирования применение, картина также популярный, потому что классы ViewModel легкий к модульному тесту. Когда логика взаимодействия приложения живет в наборе классов ViewModel вы можете легко написать код, который проверяет его. В смысл, представления и модульные тесты-это просто два различных типа ViewModel потребитель. Имея набор тестов для просмотр моделей приложение обеспечивает бесплатное и быстрое регрессионное тестирование, что помогает снизить стоимость поддержание приложения в течение долгого времени.

для меня это самая важная причина для использования MVVM.

раньше у меня были бы элементы управления, которые объединяли представление и viewmodel вместе. Но представление по существу имеет события мыши и клавиатуры в качестве входных данных и нарисованные пиксели в качестве выходных данных. Как вы тестируете что-то подобное? MVVM устраняет эту проблему, поскольку она отделяет непроверяемый вид от тестируемого viewmodel и сохраняет слой представления как можно более тонким.

прочитайте введение в MVVM в этом статьи

в 2005 году Джон Госсман, в настоящее время один из архитекторов WPF и Silverlight в Microsoft, представил шаблон Model-View-ViewModel (MVVM) в своем блоге. MVVM идентичен модели представления Фаулера, поскольку оба шаблона содержат абстракцию представления, которая содержит состояние и поведение представления. Фаулер представил модель презентация как средство создания платформо-независимый пользовательский интерфейс абстракция представления, в то время как Госсман представил MVVM как стандартизированный способ использования основных функций WPF для упрощения создания пользовательских интерфейсов. В этом смысле я считаю MVVM специализацией более общего шаблона PM, специально разработанного для платформ WPF и Silverlight.

..

В отличие от докладчика в MVP, ViewModel не нуждается в ссылке на представление. Представление привязывается к свойствам на ViewModel, который, в свою очередь, предоставляет данные, содержащиеся в объектах модели и других состояниях, специфичных для представления. Привязки между view и ViewModel просты в построении, поскольку объект ViewModel задается как DataContext представления. Если значения свойств в ViewModel изменяются, эти новые значения автоматически распространяются в представление через привязку данных. Когда пользователь нажимает кнопку в представлении, команда на ViewModel выполняется для выполнения запрошенного действия. ViewModel, никогда не вид, выполняет все изменения, внесенные в данные моделирования. Классы представления не имеют представления о существовании классов модели, в то время как ViewModel и model не знают о представлении. Фактически, модель полностью игнорирует тот факт, что ViewModel и view существуют. Это очень слабо связанный дизайн, который приносит дивиденды во многих отношениях, как вы скоро увидите.

также в статье объясняется, почему использовать эти шаблоны интерфейса:

ненужно и контрпродуктивно использовать шаблоны проектирования в a просто "Привет, Мир!" программа. Любой компетентный разработчик может понять несколько строк кода с первого взгляда. Однако по мере увеличения количества функций в программе соответственно увеличивается количество строк кода и движущихся частей. В конечном счете, сложность системы и повторяющиеся проблемы, которые она содержит, побуждают разработчиков организовывать свой код таким образом, чтобы его было легче понять, обсудить, расширить и устранить неполадки. Мы уменьшаем когнитивный хаос сложной системы путем применение известных имен к определенным сущностям в исходном коде. Мы определяем имя для применения к фрагменту кода, рассматривая его функциональную роль в системе.

разработчики часто намеренно структурируют свой код в соответствии с шаблоном проектирования, а не позволяют шаблонам появляться органично. Нет ничего плохого в любом подходе, но в этой статье я рассматриваю преимущества явного использования MVVM в качестве архитектуры приложения WPF. Имена некоторые классы включают в себя хорошо известные термины из шаблона MVVM, такие как окончание "ViewModel", если класс является абстракцией представления. Этот подход помогает избежать когнитивного хаоса, упомянутого ранее. Вместо этого вы можете счастливо существовать в состоянии управляемого хаоса, что является естественным состоянием дел в большинстве профессиональных проектов разработки программного обеспечения!

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

  1. Я активно использую RelayCommand от Джоша Смита MVVM Фонд. Это делает привязку от View к ViewModel с помощью команд намного чище.

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

  3. Мне пришлось инвертировать свой подход к тому, как программное обеспечение реализовано. Вместо того, чтобы иметь класс диктатора, который говорит всем своим миньонам, что делать, которые, в свою очередь, используют своих миньонов, мое программное обеспечение становится скорее вопросом слабо связанных услуг, которые говорят:

    • вот что я умею делать

    • вот что мне нужно было сделать

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

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


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

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

вы будете счастливы в долгосрочной перспективе, если вы используете шаблон, как MVVM по всем причинам, которые другие опубликовали. Помните, что вам не нужно следовать требованиям шаблона слово в слово, просто убедитесь, что у вас есть хорошее разделение между вашим окном (View) и вашей логикой (code-behind).

преимущества MVVM

  1. снижение сложности.
  2. изоляция проектирования и разработки.
  3. инъекции зависимостей.
  4. главное преимущество, когда у вас есть хорошо MVVM структурированное приложение для Windows Phone и вы хотите разработать то же самое для Windows Metro Desktop, единственное, что вы хотите сосредоточить на дизайне, так как одна и та же модель представления может использоваться как есть.

надеюсь, что это помогает.

MVVM-это действительно избыточный код.

Итак, какие преимущества предоставляет MVVM?

Это просто разделение проблем не более. Вы также можете записать логику ViewModel в контроллер. ViewModel просто repsonsible для выполнения преобразования (например, и объект в строку). При использовании MVVM вы используете более объектно-ориентированный стиль программирования. Записывая логику преобразования в контроллер, вы используете более функциональное программирование стиль.

таким образом, это сводится к тому, чтобы иметь больше кода с лучшей читаемостью или меньше кода с большими файлами контроллера. В заключение вы не можете сказать, что вам нужно использовать MVVM, потому что это лучше, чем MVC или так, это просто личные предпочтения.

просто чтобы было понятно, почему я упоминаю контроллер: MVVM также имеет контроллер-код где-то. Я понятия не имею, почему существует широкий консенсус покинуть С.