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

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

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

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

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

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

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

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

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

4b9b3361

Ответ 1

Резюме

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

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

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

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

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

  • "D. € |? Ré% DFA с"
  • "CorrectHorseBatteryStaple"

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

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

MVVM

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

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

Пример

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

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

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

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

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

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

Представляем модель представления

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

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

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

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

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

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

Послесловие на юнит-тестах

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

Ответ 2

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

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

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

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

Ответ 3

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

Ответ 4

От здесь:

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

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

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

Ответ 5

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

Ответ 6

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

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

Ответ 7

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

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

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

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

Ответ 8

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

  • Я активно использую RelayCommand от Josh Smith MVVM Foundation. Это значительно упрощает привязку от View to ViewModel через команды.

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

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

    • Вот что я знаю, как это сделать

    • Вот что мне нужно сделать

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

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


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

Ответ 9

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

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

..

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

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

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

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

Ответ 10

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

Ответ 11

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

Ответ 12

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

  • Уменьшенная сложность.
  • Изоляция проектирования и разработки.
  • Включение зависимостей.
  • Основным преимуществом является то, что у вас есть структурированное приложение Windows Phone с поддержкой MVVM и вы хотите разработать его для Windows Metro Desktop. Единственное, что вы хотите сконцентрироваться на дизайне, поскольку такая же модель просмотра может использоваться как есть.

Надеюсь, что это поможет.

Ответ 13

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

Так что же дает MVVM?

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

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

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