Пользователь
0,0
рейтинг
22 апреля 2013 в 12:21

Разработка → Руководство разработчика Prism — часть 5, реализация паттерна MVVM перевод tutorial

C#*, .NET*
Оглавление
  1. Введение
  2. Инициализация приложений Prism
  3. Управление зависимостями между компонентами
  4. Разработка модульных приложений
  5. Реализация паттерна MVVM
  6. Продвинутые сценарии MVVM
  7. Создание пользовательского интерфейса
    1. Рекомендации по разработке пользовательского интерфейса
  8. Навигация
    1. Навигация на основе представлений (View-Based Navigation)
  9. Взаимодействие между слабо связанными компонентами

Паттерн Model-View-ViewModel (MVVM, модель-представление-модель представления) поможет вам отделить бизнес-логику и логику представления от пользовательского интерфейса. Поддержка разделения ответственности между логикой приложения и UI может сделать ваше приложение более лёгким для тестирования, поддержки и развития. Это может также значительно улучшить возможности повторного использования кода и позволит разработчикам и дизайнерам легче сотрудничать при разработке соответствующих частей приложения.

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

Prism включает примеры и образцы реализации, которые показывают, как реализовать шаблон MVVM в Silverlight или в WPF приложениях. Библиотека Prism также предоставляет функции, которые могут помочь реализовать данный паттерн. Эти функции воплощают наиболее распространённые методы для реализации паттерна MVVM и разработаны, чтобы обеспечить тестируемость и совместимость с Expression Blend и Visual Studio.

Эта глава даёт краткий обзор паттерна MVVM и описывает, как его реализовать. Глава 6 описывает, как реализовать более сложные сценарии MVVM, используя библиотеку Prism.

Обязанности и характеристики классов


Паттерн MVVM является близкой разновидностью паттерна Presentation Model, оптимизированного для лучшего согласования с некоторыми базовыми возможностями WPF и Silverlight, такими как привязка данных, шаблоны данных, команды, и поведения.

В паттерне MVVM представление инкапсулирует UI и любую логику UI, модель представления инкапсулирует логику представления и её состояния, и модель инкапсулирует бизнес-логику и данные. Представление взаимодействует с моделью представления посредством привязки данных, команд и событий уведомления. Модель представления запрашивает данные у модели, или подписываться на уведомления об их изменении, и координирует обновления состояния модели, а также преобразует, валидирует и агрегирует, при необходимости, данные, для отображения их в представлении.

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

Классы MVVM и их взаимодействие.

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

Класс представления (View)


Представление ответственно за определение того, что пользователь видит на экране. В идеале, code-behind представления содержит только конструктор, который вызывает метод InitializeComponent. В некоторых случаях, code-behind может содержать код логики UI, который реализует визуальное поведение, являющееся трудным или неэффективным для выражения в XAML, такое как сложные анимации, или когда код должен непосредственно управлять визуальными элементами, являющимися частью представления. Недопустимо помещать код логики, нуждающийся в тестировании, в представление. Как правило, код в code-behind представления может быть протестирован через автоматизацию UI.

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

Как правило, представления наследуются от классов Control или UserControl. Однако, в некоторых случаях, представление может быть представлено шаблоном данных, который определяет элементы UI, которые будут использоваться, чтобы визуально представить объект. Используя шаблоны данных, разработчик может легко задать то, как модель представления будет визуализирована, или может изменить её визуальное представление по умолчанию, не изменяя базовый объект или его поведение непосредственно.

Шаблоны данных могут считаться представлениями, у которых отсутствует code-behind. Они разрабатываются для привязки к определённым типам модели представления, когда она должна быть отображена в UI. Во время выполнения, представление, как определено шаблоном, автоматически создаётся и соответствующая модель представления устанавливается его контекстом данных.

В WPF можно связать шаблон данных с моделью представления на уровне приложения. Тогда WPF будет автоматически применять этот шаблон данных к любым объектам модели представления указанного типа всякий раз, когда они появляются в UI. Это известно как неявные шаблоны данных. В Silverlight необходимо явно определить шаблон данных для объекта модели представления в пределах элемента управления, который должен его отображать. Шаблон данных может быть определён как встроенный в элемент управления, который его использует, или определённый в словаре ресурсов вне родительского представления и декларативно объединённый со словарём ресурсов представления.

Подводя итоги, у представления есть следующие ключевые характеристики:
  • Представление является визуальным элементом, таким как окно, страница, пользовательский элемент управления или шаблон данных. Представление определяет элементы управления, их компоновку и стиль.
  • Представление ссылается на модель представления через свое свойство DataContext. Элементы управления в представлении привязаны к свойствам и командам модели представления.
  • Представление может настроить поведение привязки данных между представлением и моделью представления. Например, представление может использовать преобразователи значений, чтобы отформатировать данные, которые будут показаны в UI, или использовать правила валидации, чтобы предоставить дополнительную проверку вводимых пользователем данных.
  • Представление задаёт и обрабатывает визуальное поведение UI, такое как анимации или переходы, которые могут быть инициированы изменением состояния модели представления, или через взаимодействие пользователя с UI.
  • Code-behind представления может определить логику UI, чтобы реализовать некоторое визуальное поведение, которое трудно выразить в XAML, или которое требует прямых ссылок на определённые элементы управления UI, определённые в представлении.

Класс модели представления (View Model)


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

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

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

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

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

В итоге, модель представления имеет следующие ключевые характеристики:
  • Является не визуальным классом и не наследуется ни от какого базового класса WPF или Silverlight. Она инкапсулирует логику представления, необходимую для поддержки пользовательских действий в приложении. Модель представления тестируется независимо от представления и модели.
  • Обычно непосредственно не ссылается на представление. Она реализует свойства и команды, к которыми представление может привязать данные. Она уведомляет представление о любых изменениях состояния через события уведомления интерфейсов INotifyPropertyChanged и INotifyCollectionChanged.
  • Координирует взаимодействие представления с моделью. Она может преобразовать или управлять данными так, чтобы их можно было легко использовать представлению, и может реализовать дополнительные свойства, которые, возможно, не присутствуют в модели. Она может также реализовать валидацию данных через интерфейсы IDataErrorInfo или INotifyDataErrorInfo.
  • Может определить логические состояния, которые представление может визуально представить пользователю.

Заметка. Представление или модель представления?
Часто определение того, где должна быть реализована определённая функциональность, не очевидно. Общее правило гласит: Что-либо касающееся определённого визуального отображения и что может быть модернизировано позже (даже если вы в настоящий момент не планируете модернизировать это), должно войти в представление; что-либо, что важно для логики приложения, должно войти в модель представления. Кроме того, так как у модели представления не должно быть никаких явно заданных знаний об определённых визуальных элементах в представлении, код, чтобы программно управлять визуальными элементами в пределах представления, должен находиться в code-behind представления или инкапсулироваться в поведениях (Behaviors). Точно так же, код для получения или управления элементами данных, которые должны быть показаны в представлении посредством привязки данных, должен находиться в модели представления. Например, цвет выделения выбранного пункта в поле списка должен быть определён в представлении, но список элементов для отображения и ссылка на выбранный пункт, должны быть определены в модели представления.

Класс модели (Model)


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

Как правило, модель представляет сущность предметной области клиентской части приложения. Она может содержать структуры данных, основанные на модели данных приложения и любую бизнес и логику валидации. Модель может также иметь доступ к данным и кэшу, хотя обычно для этого используется отдельный репозиторий данных, или соответствующая служба. Часто, модель и слой доступа к данным являются автоматически сгенерированными, как часть инфраструктуры ADO.NET Entity Framework, WCF Data Services, или WCF RIA Services.

Как правило, модель реализует средства, облегчающие привязку к представлению. Это обычно означает, что поддерживаются уведомления об изменениях свойств или коллекций через интерфейсы INotifyPropertyChanged и INotifyCollectionChanged. Классы моделей, которые предоставляют наборы объектов, обычно наследуются от класса ObservableCollection, который предоставляет реализацию интерфейса INotifyCollectionChanged. Модель может также поддерживать валидацию данных и сообщение об ошибках через интерфейсы IDataErrorInfo (или INotifyDataErrorInfo). Эти интерфейсы позволяют посылать WPF и Silverlight уведомления для обновления UI, когда значения привязанных данных изменяются. Они также предоставляют поддержку валидации данных и сообщения об ошибках в уровне UI.
Заметка
Что, если Ваши классы модели не реализуют необходимые интерфейсы?
Иногда Вы должны будете работать с объектами модели, которые не реализуют интерфейсы INotifyPropertyChanged, INotifyCollectionChanged, IDataErrorInfo, или INotifyDataErrorInfo. В этих случаях модель представления, возможно, должна будет обернуть объекты модели и предоставить необходимые свойства представлению. Значения для этих свойств будут предоставлены непосредственно объектами модели. Модель представления сможет реализовать необходимые интерфейсы для свойств, которые она предоставляет так, чтобы представление могло легко привязать к ним данные.

У модели есть следующие ключевые характеристики:
  • Классы модели являются не визуальными классами, которые инкапсулируют данные приложения и бизнес-логику. Они ответственны за управление данными приложения и за обеспечение их непротиворечивости и валидности, инкапсулируя необходимые бизнес-правила и логику валидации данных.
  • Классы модели непосредственно не ссылаются на классы представления или модели представления и не имеют никакой зависимости от того, как эти классы реализуются.
  • Классы модели обычно предоставляют уведомления об изменении свойств или коллекций через интерфейсы INotifyPropertyChanged и INotifyCollectionChanged. Это позволяет им быть легко привязанными к представлению. Классы модели, которые представляют коллекции объектов, обычно наследуются от класса ObservableCollection.
    Классы модели обычно обеспечивают валидацию данных и сообщение об ошибках через интерфейсы IDataErrorInfo, или INotifyDataErrorInfo.
    Классы модели обычно используются вместе со службой или репозиторием, который инкапсулирует доступ к данным и кэширование.
Перевод: microsoft patterns & practices
Николай Фёдоров @Unrul
карма
61,0
рейтинг 0,0
Реклама помогает поддерживать и развивать наши сервисы

Подробнее
Реклама

Самое читаемое Разработка

Комментарии (2)

  • 0
    пожайлуста не минусуйте, я думал вообще коментарии не работают, раз никто не ответил за час.
    • 0
      Что ж тут отвечать… Круто, спасибо.

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