Бессмысленна ли ортодоксальная реализация MVVM? Я создаю новое приложение и рассмотрел Windows Forms и WPF. Я выбрал WPF, потому что он ориентирован на будущее и предлагает большую гибкость. Меньше кода и проще вносить существенные изменения в пользовательский интерфейс с помощью XAML.
Поскольку выбор WPF очевиден, я подумал, что могу пойти до конца, используя MVVM в качестве архитектуры приложения, поскольку он предлагает смешиваемость, проблемы разделения и возможность тестирования модулей. Теоретически это кажется прекрасным, как святой Грааль программирования пользовательского интерфейса. Это короткое приключение; Однако превратилось в настоящую головную боль. Как и ожидалось на практике, я обнаружил, что поменял одну проблему на другую. Я склонен быть одержимым программистом в том смысле, что хочу делать все правильно, чтобы получить правильные результаты и, возможно, стать лучшим программистом. Шаблон MVVM только что провалил мой тест на продуктивность и превратился в большой противный хакер!
Ярким примером является добавление поддержки модального диалогового окна. Правильный способ - создать диалоговое окно и привязать его к модели представления. Заставить это работать сложно. Чтобы извлечь выгоду из шаблона MVVM, вам необходимо распределить код в нескольких местах по слоям вашего приложения. Вы также должны использовать такие эзотерические программные конструкции, как шаблоны и лямба-выражения. Вещи, которые заставляют смотреть в экран, почесывая затылок. Как я недавно обнаружил, это превращает обслуживание и отладку в кошмар, ожидающий своего часа. У меня было окно about, работающее нормально, пока я не получил исключение во второй раз, когда я вызвал его, говоря, что он не может снова показать диалоговое окно после его закрытия. Мне пришлось добавить обработчик событий для функции закрытия диалогового окна, еще один в его реализации IDialogView и, наконец, еще один в IDialogViewModel. Я думал, что MVVM спасет нас от такого экстравагантного взлома!
Есть несколько людей, предлагающих конкурирующие решения этой проблемы, и все они являются хакерскими приемами и не обеспечивают чистого, легко повторяемого и элегантного решения. Большинство наборов инструментов MVVM затушевывают диалоги, и когда они обращаются к ним, они представляют собой просто окна предупреждений, которые не требуют настраиваемых интерфейсов или моделей просмотра.
Я планирую отказаться от шаблона представления MVVM, по крайней мере, от его ортодоксальной реализации. Что вы думаете? Стоило ли вам хлопот, если они у вас были? Я просто некомпетентный программист или MVVM не такой, как его рекламируют?
Ответы:
Извините, если мой ответ стал немного длинным, но не вините меня! Ваш вопрос тоже длинный.
Таким образом, MVVM не бесполезен.
Да, действительно так.
Однако MVVM позволяет отделить внешний вид пользовательского интерфейса от его логики. Никто не заставляет вас использовать его везде, и никто не держит пистолет у вашего лба, чтобы заставить вас создать отдельную ViewModel для всего.
Вот мое решение для этого конкретного примера:
как пользовательский интерфейс обрабатывает определенный ввод, не является делом ViewModel. Я бы добавил код в файл View .xaml.cs, который создает экземпляр диалогового окна и устанавливает тот же экземпляр ViewModel (или что-то еще, если необходимо) в качестве его DataContext.
Что ж, вам не обязательно использовать его в нескольких местах. Вот как я бы это решил:
Я думаю, что цель MVVM - в первую очередь разделить логику приложения и конкретный пользовательский интерфейс, что позволяет легко модифицировать (или полностью заменять) пользовательский интерфейс.
Я использую следующий принцип: View может знать и предполагать все, что хочет от ViewModel, но ViewModel НИЧЕГО не может знать о View.
WPF предоставляет удобную модель привязки, которую вы можете использовать для достижения именно этого.
(Кстати, шаблоны и лямбда-выражения не являются эзотерическими, если используются правильно. Но если вы не хотите, не используйте их.)
Да, я знаю это чувство. Именно то, что я почувствовал, когда впервые увидел MVVM. Но как только вы освоитесь, это больше не будет плохо.
Зачем помещать ViewModel за окном «О нас»? Нет смысла в этом.
Да, потому что сам факт, что элемент пользовательского интерфейса находится в том же окне, или другом окне, или вращается на орбите Марса в данный момент, не касается ViewModels.
Разделение проблем
РЕДАКТИРОВАТЬ:
Вот очень красивое видео под названием « Создайте свой собственный фреймворк MVVM» . Стоит посмотреть.
источник
Для обычного модального диалогового окна? Вы определенно делаете что-то не так - реализация MVVM не должна быть такой сложной.
Учитывая, что вы новичок как в MVVM, так и в WPF, вполне вероятно, что вы везде используете неоптимальные решения и излишне усложняете ситуацию - по крайней мере, я сделал это, когда впервые перешел на WPF. Прежде чем сдаваться, убедитесь, что проблема действительно в MVVM, а не в вашей реализации.
MVVM, MVC, Document-View и т. Д. - это старое семейство шаблонов. Есть недостатки, но нет фатальных недостатков того типа, который вы описываете.
источник
Я нахожусь в середине довольно сложной разработки MVVM с использованием PRISM, поэтому мне уже приходилось справляться с такими проблемами.
Мои личные выводы:
MVVM против MVC / PopUps & co
источник
Я решаю проблему с диалогами обманом. 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 великолепен. Но библиотека управления WPF, поставляемая с поддержкой привязки данных NET 4.0, очень ограничена, она намного лучше, чем WinForm, но все же ее недостаточно для привязываемого MVVM, я бы сказал, что ее мощность составляет около 30% от того, что необходимо для привязываемого MVVM.
Связываемый MVVM: это пользовательский интерфейс, в котором ViewModel связан с View только с использованием привязки данных.
Шаблон MVVM касается объектного представления ViewState, он не описывает, как вы поддерживаете синхронизацию между View и ViewModel, в WPF это привязка данных, но это может быть что угодно. И на самом деле вы можете использовать шаблон MVVM в любом наборе инструментов пользовательского интерфейса, который поддерживает события \ обратные вызовы, вы можете использовать его в чистом WinAPI в WinForms (я сделал, и это не намного больше работы с событиями \ обратными вызовами), и вы даже можете использовать его в тексте Консоль, как переписать DoS Norton Commander с использованием шаблона MVVM.
Вкратце: MVVM не бесполезен, это здорово. Библиотека элементов управления WPF в .NET 4.0 - это мусор.
Вот простое доказательство концепции ViewModel, которую вы не можете привязать к данным чистым способом MVVM с использованием WPF.
public class PersonsViewModel { public IList<Person> PersonList; public IList<ColumnDescription> TableColumns; public IList<Person> SelectedPersons; public Person ActivePerson; public ColumnDescription SortedColumn; }
Вы не можете привязать данные к заголовкам столбцов WPF DataGrid, вы не можете привязать данные к выбранным строкам и т.д. и т.д., вы либо сделаете это простым кодом, либо напишите 200 строк кода взлома XAML для этих 5 строк простейшей модели ViewModel. Вы можете только представить, насколько хуже обстоят дела со сложными ViewModels.
Так что ответ прост, если вы не пишете приложение Hello World, использование привязываемого MVVM в WPF бессмысленно. Вы потратите большую часть своего времени на размышления о взломе, чтобы привязать вас к ViewModel. Связывание данных - это хорошо, но будьте готовы вернуться к событию в 70% случаев.
источник
Нет, это не бессмысленно, но сложно обдумать, хотя сам узор смехотворно прост. Существует масса дезинформации и различные группы, которые борются за правильный путь. Я думаю, что с WPF и Silverlight вам следует использовать MVVM, иначе вы будете чрезмерно кодировать и пытаться решать проблемы в новой модели, используя «старую» методологию форм выигрыша, которая просто приводит вас к неприятностям. Это в большей степени относится к Silverlight, поскольку все должно быть асинхронным (в этом случае возможны взломы, но вы должны просто выбрать другую платформу).
Я бы посоветовал внимательно прочитать эту статью « Упрощение WPF TreeView с помощью шаблона ViewModel», чтобы увидеть, как можно хорошо реализовать MVVM, и позволит вам изменить менталитет форм выигрыша на новый образ мышления в MVVM. Короче говоря, когда вы хотите что-то сделать, сначала примените логику к ViewModel, а не к View. Вы хотите выбрать товар? Изменить значок? Не повторяйте элементы пользовательского интерфейса, просто обновите свойства модели и позвольте привязке данных сделать все возможное.
источник
Я видел ту же проблему во многих реализациях MVVM, когда дело дошло до (модальных) диалогов. Когда я смотрю на участников шаблона MVVM, у меня возникает ощущение, что чего-то не хватает для создания согласованного приложения.
Но не хватает:
Мой подход состоит в том, чтобы представить контроллер (прецедента) который отвечает за недостающие точки. Как это работает, можно увидеть в примерах приложений WPF Application Framework (WAF) .
источник