Является ли MVVM бессмысленным? [закрытый]


является ли православная реализация MVVM бессмысленной? Я создаю новое приложение, и я рассмотрел Windows Forms и WPF. Я выбрал WPF, потому что он защищен от будущего и предлагает большую гибкость. Существует меньше кода и проще вносить существенные изменения в пользовательский интерфейс с помощью XAML.

поскольку выбор для WPF очевиден, я решил, что я могу также пройти весь путь, используя MVVM в качестве архитектуры приложения, поскольку он предлагает совместимость, проблемы разделения и модульную тестируемость. Теоретически, это кажется красивым, как Святой Грааль программирования пользовательского интерфейса. Это короткое приключение, однако, превратилось в настоящую головную боль. Как и ожидалось на практике, я обнаружил, что обменял одну проблему на другую. Я склонен быть одержимым программистом в том, что я хочу делать все правильно, чтобы я мог получить правильные результаты и, возможно, стать лучшим программистом. Шаблон MVVM просто завалил мой тест на производительность и только что превратился в большой Гадкий Хак!

в ясный пример - это добавление поддержки модального диалогового окна. Правильный способ-создать диалоговое окно и привязать его к модели представления. Заставить это работать трудно. Чтобы извлечь выгоду из шаблона MVVM, вам нужно распределить код в нескольких местах по всем слоям вашего приложения. Вы также должны использовать эзотерические программные конструкции, такие как шаблоны и выражения lamba. Вещи, которые заставляют вас смотреть на экран, почесывая голову. Это делает обслуживание и отладку a кошмаром, как я недавно обнаружил. У меня было окно about, работающее нормально, пока я не получил исключение во второй раз, когда я вызвал его, сказав, что он не может снова показать диалоговое окно после его закрытия. Мне пришлось добавить обработчик событий для близких функций в диалоговое окно, еще один в реализации IDialogView и, наконец, еще один в IDialogViewModel. Я думал, что MVVM спасет нас от такого экстравагантного хакерства!

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

Я планирую отказаться от шаблона представления MVVM, по крайней мере, его ортодоксальной реализации. А ты как думаешь? Стоило ли вам беспокоиться, если бы они у вас были? Я просто некомпетентный программист или MVVM не то, что он раздут, чтобы быть?

8 89

8 ответов:

Извините, если мой ответ стал немного длинноватым, но не вините меня! Ваш вопрос тоже длинный.

таким образом, MVVM не является бессмысленным.

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

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

вот мое решение для этого конкретного примера:
То, как пользовательский интерфейс обрабатывает определенный ввод, не относится к бизнесу ViewModel. Я бы добавил код к представлению .код XAML.cs-файл, который создает экземпляр диалогового окна и устанавливает тот же экземпляр ViewModel (или что-то еще, если это необходимо), что и его свойство DataContext.

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

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

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

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

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

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

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

У меня была коробка, работающая нормально ...

Почему бы вам поставить ViewModel За о коробке? В этом нет смысла.

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

Да, потому что сам факт, что элемент пользовательского интерфейса в том же окне, или другое окно, или находится на орбите Марса в данный момент, не является проблемой ViewModels.
разделение

EDIT:

вот очень хорошее видео, название которого создайте свой собственный фреймворк MVVM. Это стоит посмотреть.

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

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

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

MVVM, MVC, Document-View и др. это старинное семейство узоров.. Есть недостатки, но нет фатальных недостатков, которые вы описываете.

Я имею дело с проблемой диалогов путем обмана. My MainWindow реализует интерфейс IWindowServices, который предоставляет все диалоговые окна для конкретных приложений. Мои другие ViewModels могут затем импортировать интерфейс служб (я использую MEF, но вы можете легко просто передать интерфейс через конструкторы вручную) и использовать его для выполнения того, что необходимо. Например, вот как выглядит интерфейс для моего небольшого служебного приложения:

//Wrapper interface for dialog functionality to allow for mocking during tests
public interface IWindowServices
{
    bool ExecuteNewProject(NewProjectViewModel model);

    bool ExecuteImportSymbols(ImportSymbolsViewModel model);

    bool ExecuteOpenDialog(OpenFileDialog dialog);

    bool ExecuteSaveDialog(SaveFileDialog dialog);

    bool ExecuteWarningConfirmation(string text, string caption);

    void ExitApplication();
}

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

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

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

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

Я нахожусь в середине довольно сложной разработки MVVM с использованием PRISM, поэтому мне уже приходилось справляться с такого рода проблемами.

мои личные выводы:

MVVM vs MVC / PopUps & co

  • MVVM действительно отличный шаблон и в большинстве случаев он полностью заменяет MVC благодаря мощной привязке данных в WPF
  • вызов вашего сервисного уровня непосредственно из презентатора является законной реализацией в большинстве случаев
  • даже довольно сложные сценарии List / Detail могут быть реализованы чистым MVVM благодаря синтаксису {Binding Path=/}
  • тем не менее, когда необходимо реализовать сложную координацию между несколькими представлениями, контроллер в обязательном порядке
  • могут использоваться события; старый шаблон, который подразумевает хранение экземпляров IView( или AbstractObserver) в контроллере, устарел
  • контроллер может быть введен в каждый презентатор контейнером IOC
  • призмы Служба IEventAggregator является еще одним возможным решением, если единственным использованием контроллера является диспетчеризация событий (в этом случае он может полностью заменить контроллер)
  • если представления должны быть динамически созданы, это очень хорошо подходит работа для контроллера (в prism контроллер будет введен (IOC) A IRegionManager)
  • модальные диалоговые окна в основном устарели в современных составных приложениях, за исключением действительно блокирующих операций, таких как обязательные подтверждения; в в этих случаях модальная активация может быть абстрагирована как служба, вызываемая внутри контроллера, и реализована специализированным классом, который также позволяет проводить расширенное модульное тестирование на уровне представления. Контроллер, например, вызовет IConfirmationService.RequestConfirmation ("вы уверены"), который вызовет модальное диалоговое окно во время выполнения и может быть легко высмеян во время модульного тестирования

Как и сам шаблон MVVM велик. Но библиотека управления WPF, поставляемая с поддержкой привязки данных NET 4.0, очень ограничена, это намного лучше, чем WinForm, но все же этого недостаточно для bindable MVVM, я бы сказал, что это мощность около 30% от того, что необходимо для bindable MVVM.
Bindable MVVM: это пользовательский интерфейс, в котором ViewModel подключается к View только с помощью привязки данных.
Шаблон MVVM относится к представлению объекта ViewState, он не описывает, как вы поддерживаете синхронизацию между View и ViewModel, в WPF это привязка данных, но это может быть что угодно. И на самом деле вы можете использовать шаблон MVVM шаблон в любом пользовательского интерфейса инструментальных средств, которые поддерживают события\обратные вызовы, вы можете использовать его в чистом WinAPI в (В я делал, и это не намного больше работы с событиями\обратные вызовы), и вы можете даже использовать его в текстовой консоли, как переписать DOS и Нортон Коммандер, используя шаблоне MVVM.

короче говоря: MVVM не бессмысленно, это здорово. Библиотека управления NET 4.0 WPF-это корзина.

здесь это простое доказательство концепции ViewModel, которое вы не можете привязать данные в чистом виде MVVM с помощью WPF.

public class PersonsViewModel
{
    public IList<Person> PersonList;
    public IList<ColumnDescription> TableColumns;
    public IList<Person> SelectedPersons;
    public Person ActivePerson;
    public ColumnDescription SortedColumn;
}

вы не можете привязать данные к заголовкам столбцов DataGrid WPF, вы не можете привязать данные к выбранным строкам и т. д. и т. д., Вы либо сделаете это простым способом кода, либо напишите 200 строк кода XAML для этих 5 строк простейшей ViewModel. Вы можете только представить, как все становится хуже со сложными ViewModels.
Поэтому ответ прост, если вы не пишете приложение Hello World, использование bindable MVVM в WPF бессмысленно. Вы будете тратить большую часть своего времени, думая о взломе, чтобы связать вас ViewModel. Привязка данных хороша, но будьте готовы вернуться к событию в 70% случаев.

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

  • View содержит определенные элементы управления GUI и определяет внешний вид пользовательского интерфейса.
  • ViewModel представляет состояние и поведение демонстрация.
  • модель может быть бизнес-объектом из уровня домена или сервисом, который предоставляет необходимые данные.

но:

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

мой подход заключается в том, чтобы ввести (Use-Case)контроллер который отвечает за недостающие баллы. Как это работает можно увидеть на WPF Application Framework (WAF) образцы заявлений.

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

Я бы предложил прочитать эту статью упрощение WPF TreeView с помощью шаблона ViewModel внимательно посмотреть, как MVVM может быть реализован хорошо и позволит вам изменить свой менталитет win forms на новый способ мышления в MVVM. Короче говоря, когда вы хотите что-то сделать, примените логику к ViewModel, а не к представлению. Вы хотите выбрать предмет? Изменить значок? Не перебирайте элементы пользовательского интерфейса, просто обновите свойства моделей и позвольте привязке данных сделать nitty gritty.