Реализация паттерна MVVM на примере C# (WPF). «Нестрогий» вариант

Model-View-ViewModel (MVVM) – архитектурный паттерн, ориентированный главным образом на платформы, поддерживающие связывание данных и элементов пользовательского интерфейса (например, WPF).

MVVM сравнительно «молодой» паттерн (впервые представлен Джоном Госсманом в 2005 году [1]).

Описание паттерна MVVM

MVVM преследует те же цели, что и MVC. Разделить бизнес-логику и пользовательский интерфейс. Однако в MVC изменения, производимые пользователем при работе с интерфейсом, не влияют непосредственно на модель, а предварительно обрабатываются Контроллером. В MVVM происходит двустороннее связывание.

Различие между этими паттернами лучше можно схематично представить следующими диаграммами.

Паттерн MVVM

 

Паттерн MVC

Паттерн MVVM состоит из следующих компонентов:

  • Модель (англ. Model)
    Представляет собой бизнес-логику приложения;
  • Представление (англ. View)
    Графический интерфейс для работы с данными или их отображения (окна, кнопки, таблицы и т.д.);
  • Модель представления (англ. ViewModel)
    Обёртка подлежащих связыванию данных из модели, которая содержит методы, которые используются представлением для работы с моделью.

Применительно к WPF, окно приложения, это представление (всегда). Остальные компоненты паттерна принято реализовывать в виде не визуальных классов. Подробнее реализация MVVM в WPF будет рассмотрена далее на прикладном примере.

Пример реализации

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

Модель

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

Для обеспечения возможности связывания требуется, чтобы можно было отслеживать изменения в модели. Поэтому её класс должен реализовывать интерфейс INotifyPropertyChanged (пространство имён System.ComponentModel).

Ниже приведён код этого класса:

Если не считать требования по реализации интерфейса INotifyPropertyChanged, то, как и в большинстве случаев, данная модель представляет собой обычный «сущностный» класс.

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

Модель представления является по сути посредником между представлением и моделью. Для поддержки связывания модель представления также должна реализовывать интерфейс INotifyPropertyChanged.

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

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

Также включим в модель представления два метода. Для добавления нового автомобиля и удаления уже существующего.

Методов для редактирования не добавляем так как необходимый функционал полностью обеспечивается за счёт связывания.

«Строгий» и «нестрогий» варианты реализации

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

Ниже приведён полный исходный код класса модели представления.

Представление

Как уже говорилось ранее, в случае WPF представление, это окно приложения.

«Строгий» и «нестрогий» варианты реализации

При «строгой» реализации в коде окна присутствует только инициализация модели представления в конструкторе.

При «нестрогой» добавляются методы событийной модели для работы с данными. В данном случае это обработчики кликов для кнопок добавления и удаления автомобилей соответственно.

Связывание конкретный элементов управления с данными осуществляется в XAML.

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

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

Резюме

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

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

Но, всё это хорошо для достаточно сложных проектов на соответствующих платформах.

Для простых программ MVVM (также, как и MVC) создаёт лишь ничем неоправданные сложности. А, если платформа не поддерживает связывание (например, Windows Forms), то сама реализация паттерна MVVM усложняется на порядок и в этом случае гораздо эффективнее использовать другие паттерны, которым связывание не требуется.

Источники

  1. Model-View-ViewModel (Википедия)
  2. Model-View-Controller (Википедия)

Добавить комментарий

Ваш адрес email не будет опубликован. Обязательные поля помечены *