Рефакторинг раздутой модели представления - PullRequest
15 голосов
/ 25 марта 2010

Я пишу приложение PRISM / MVVM / WPF. Это LOB-приложение, поэтому есть много сложных правил. Я заметил, что модель представления начинает раздуваться. Есть два основных вопроса.

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

Другая проблема - это количество команд в моей виртуальной машине. Прямо сейчас есть четыре команды. Я определяю команды в виртуальной машине с помощью RelayCommand Джоша Смита (в основном это DelegateCommand в PRISM), поэтому вся бизнес-логика живет в виртуальной машине. Я рассмотрел вопрос о переводе каждой команды в отдельный блок работ. Я не уверен, что лучший способ сделать это.

Какие шаблоны вы, ребята, используете для поддержания чистоты своих виртуальных машин? Я уже чувствую, что кто-то отвечает «ваш взгляд и ВМ слишком сложны, вы должны разбить их на множество представлений / ВМ». Это, конечно, не слишком сложно с точки зрения Ux - есть 2 кнопки, поле со списком и список. Кроме того, с логической точки зрения, это одна сплоченная область. Сказав это, мне очень интересно услышать, как другие решают эту проблему.

Спасибо за ваш вклад.

Ответы [ 3 ]

4 голосов
/ 25 марта 2010

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

Я склонен очень беспокоиться о «раздутии» в моем базовом классе ViewModel, но не так сильно в конкретных подклассах ViewModel. Часто заманчиво бросить зависимость, используемую 2-3 ViewModels, в базовый класс, но этого следует избегать.

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

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

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

0 голосов
/ 25 января 2012

У меня есть две основные мысли по этому поводу, но YMMV.

Во-первых, я бы переместил специфичный для реализации код из виртуальной машины в «сервис», который по сути является просто классом, который выполняет эту работу. Это может быть, например, класс customerService, в котором есть реализация методов сохранения, удаления, обновления, а реализация RelayCommand будет вызывать службу для выполнения действия и обновлять любые свойства представления соответствующим образом.

Примером может быть то, что RelayCommand может установить значение свойства «ShowProgressBar», которое связано с видимостью индикатора выполнения. Затем он вызвал бы функцию сохранения в сервисе, а по завершении (это должно быть асинхронно, между прочим) должен снова обновить «ShowProgressBar». Таким образом, ViewModel контролирует состояние View независимо от логики основного приложения.

Во-вторых, я бы посмотрел на используемую вами базовую модель представления и постарался максимально упростить ее, добавляя только компоненты, общие для всех ваших моделей представления. Затем вы можете создать другие модели базовых представлений или интерфейсы в зависимости от ситуации. Например, вы можете решить, что все ваши модели представлений будут предоставлять свойство ShowProgressBar, которое может быть связано с индикатором выполнения на вашей странице, или вы можете создать ProgressViewModelBase или IAllowProgress, которые вы унаследуете / внедрите на страницах, для которых требуются индикаторы выполнения.

В самом представлении должно быть как можно меньше кода, вы должны стремиться к нулю кода (хотя, к сожалению, есть вещи, которые можно сделать только в коде).

Одна вещь, которую я обнаружил, к моему ущербу, заключается в том, что создание сложных моделей представления может быть дорогостоящим с точки зрения производительности, особенно если вы регистрируете команды relay и источники / слушатели агрегатора событий, поэтому поддержание базовой модели представления очень полезно для нас. Это особенно важно, если вы используете ViewModelCollections для отображения списков объектов Model, и когда создание ViewModel происходит в потоке пользовательского интерфейса (что, вероятно, если ViewModel создается при создании представления).

0 голосов
/ 25 марта 2010

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

Не могли бы вы подробнее рассказать о вашей ViewModel?

РЕДАКТИРОВАТЬ На основе комментариев.

SaveCustomer и DeleteCustomer похожи на методы Model или Service, поэтому я бы поместил их в какой-нибудь слой постоянства.

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

Как правило, стоит поместить общий код (который может потребоваться использовать несколько ViewModel) в Сервис, а затем добавить этот сервис в ваш IOC. Таким образом, ваши ViewModels становятся легкими «директорами» информации из View в Модель или Сервис.

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...