Краткое руководство по MVVM: ключевые моменты и примеры

Иван Шарый

MVVM (Model-View-ViewModel) — способ организации кода. Он помогает отделить пользовательский интерфейс от логики.

Паттерн MVVM

  • View содержит только код пользовательского интерфейса. Он отображает экран (текстовые поля, ярлыки, кнопки) и пользовательский ввод. Например, в Windows Forms это обычно Form или Control. В Windows Presentation Foundation (WPF) — это класс Window: файлы XAML и xaml.cs.
  • Model — это классы. Это «вещи» в вашей программе. Например, в программе ввода заказов вашими классами моделей могут быть: Customer, Order, InventoryItem. Эти классы будут содержать логику, необходимую для выполнения функций.
  • ViewModel используются для связи между View и Model. Они обычно не содержат много логики. Они содержат Model, который должен быть использован во View. Когда человек взаимодействует с пользовательским интерфейсом, ViewModel узнает, какое действие необходимо выполнить, и просит Model сделать это.

Как работает паттерн MVVM?

Как работает паттерн MVVM можно разобрать на примере из реального мира. Представьте, что у нас есть владелец интернет-магазина, веб-мастер и контент-менеджер:

  • владелец интернет-магазина (Model) — занимается своей работой, ни на что не отвлекаясь. Если начинается важная акция, он передает веб-мастеру, что нужно добавить новость о ней в блог;
  • веб-мастер (ViewModel) – получает информацию от владельца интернет-магазина и передает ее контент-менеджеру;
  • контент-менеджер (View) — пишет новость в блог, основываясь на данных, которые предоставил веб-мастер, и публикует ее.

Примеры использования MVVM

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

В WPF View проектируется с помощью языка разметки XAML. Файлы XAML привязываются к ViewModel. Таким образом View отвечает только за представление, а ViewModel — только за управление состоянием приложения.

MVVM очень широко используется в JavaScript-библиотеке Knockout.js.

Реализация паттерна MVVM

Рассмотрим следующую реализацию MVVM с использованием C#, .NET и WPF.

У нас есть класс Model под названием Animals, класс View, реализованный в XAML, и модель ViewModel под названием AnimalViewModel. Обратите внимание, что Model ни о чем не знает, ViewModel знает только о модели, а View знает только о ViewModel.

Событие OnNotifyPropertyChanged-event позволяет обновлять и Model, и View так, что когда вы вводите что-то в текстовое поле во View, Model обновляется. И если что-то обновляет Model, то обновляется и View:

/*Model class*/
public class Animal 

{
    public string Name { get; set; }

    public string Gender { get; set; }
}

/*ViewModel class*/
public class AnimalViewModel : INotifyPropertyChanged

{
    private Animal _model;

    public AnimalViewModel()

    {
        _model = new Animal {Name = "Cat", Gender = "Male"};
    }

    public string AnimalName

    {
        get { return _model.Name; }

        set

        {
            _model.Name = value;

            OnPropertyChanged("AnimalName");
        }
    }

    public string AnimalGender

    {
        get { return _model.Gender; }

        set

        {
            _model.Gender = value;

            OnPropertyChanged("AnimalGender");
        }
    }

    //Event binds view to ViewModel.

    public event PropertyChangedEventHandler PropertyChanged;

    protected virtual void OnPropertyChanged(string propertyName)

    {
        if (this.PropertyChanged != null)

        {
            var e = new PropertyChangedEventArgs(propertyName);

            this.PropertyChanged(this, e);
        }
    }
}


<!-- Xaml View -->

<Window x:Class="WpfApplication6.MainWindow"

        xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"

        xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"

        Title="MainWindow" Height="350" Width="525"

        xmlns:viewModel="clr-namespace:WpfApplication6">

    <Window.DataContext>

        <viewModel:AnimalViewModel/>

    </Window.DataContext>

    <StackPanel>

        <TextBox Text="{Binding AnimalName}" Width="120" />

        <TextBox Text="{Binding AnimalGender}" Width="120" />

    </StackPanel>

</Window>

Изменение кода с помощью MVVM

Давайте посмотрим на код, написанный без использования MVVM. Проблема в том, что единственный способ проверить логику — это вручную запустить программу и ввести значения для каждого сценария:

using System.Linq;

using System.Windows;

namespace WorkbenchWPF.MVVMPattern.NonPatternVersion

{
    public partial class AccountCreationView : Window

    {
        public AccountCreationView()

        {
            InitializeComponent();
        }

        private void OnClick_ValidatePassword(object sender, RoutedEventArgs e)

        {
            if(txtPassword.Text.Trim().Length < 8)

            {
                lblErrorMessage.Text = "Password must be at least eight characters long";

            }

            else if(txtPassword.Text.Trim().Length > 20)

            {
                lblErrorMessage.Text = "Password cannot be more than twenty characters long";
            }

            else if(!txtPassword.Text.Any(char.IsUpper))

            {

                lblErrorMessage.Text = "Password must contain at least one upper-case character";
            }

            else if(!txtPassword.Text.Any(char.IsLower))

            {
                lblErrorMessage.Text = "Password must contain at least one lower-case character";
            }

            else if(!txtPassword.Text.Any(char.IsNumber))

            {
                lblErrorMessage.Text = "Password must contain at least one number";
            }

            else

            {
                lblErrorMessage.Text = "Password is secure";
            }
        }
    }
}

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

using System.Windows;

using Engine.MVVMPattern.PatternVersion.ViewModels;
namespace WorkbenchWPF.MVVMPattern.PatternVersion
{
   public partial class AccountCreationView : Window
   {
     private readonly AccountCreationViewModel _viewModel = new AccountCreationViewModel();
       public AccountCreationView()
       {
           InitializeComponent();
           DataContext = _viewModel;
       }
       private void OnClick_ValidatePassword(object sender, RoutedEventArgs e)
       {
           _viewModel.ValidatePassword();
       }
   }
} 

Ключевые моменты паттерна MVVM

  • Пользователь взаимодействует с View.
  • View имеет ссылку на ViewModel, но View Model не имеет информации о View.
  • Поддерживается двустороннее связывание данных между View и ViewModel.

Останні статті

Обучение Power BI – какие онлайн курсы аналитики выбрать

Сегодня мы поговорим о том, как выбрать лучшие курсы Power BI в Украине, особенно для…

13.01.2024

Work.ua назвал самые конкурентные вакансии в IТ за 2023 год

В 2023 году во всех крупнейших регионах конкуренция за вакансию выросла на 5–12%. Не исключением…

08.12.2023

Украинская IT-рекрутерка создала бесплатный трекер поиска работы

Unicorn Hunter/Talent Manager Лина Калиш создала бесплатный трекер поиска работы в Notion, систематизирующий все этапы…

07.12.2023

Mate academy отправит работников в 10-дневный оплачиваемый отпуск

Edtech-стартап Mate academy принял решение отправить своих работников в десятидневный отпуск – с 25 декабря…

07.12.2023

Переписки, фото, история браузера: киевский программист зарабатывал на шпионаже

Служба безопасности Украины задержала в Киеве 46-летнего программиста, который за деньги устанавливал шпионские программы и…

07.12.2023

Как вырасти до сеньйора? Девелопер создал популярную подборку на Github

IT-специалист Джордан Катлер создал и выложил на Github подборку разнообразных ресурсов, которые помогут достичь уровня…

07.12.2023