MVVM (Model-View-ViewModel) — способ организации кода. Он помогает отделить пользовательский интерфейс от логики.
Как работает паттерн MVVM можно разобрать на примере из реального мира. Представьте, что у нас есть владелец интернет-магазина, веб-мастер и контент-менеджер:
Основным примером использования MVVM является программирование графического интерфейса пользователя (GUI). Он используется для простого событийно-управляемого программирования пользовательских интерфейсов путем отделения View от логики бэкенда, управляющей данными.
В WPF View проектируется с помощью языка разметки XAML. Файлы XAML привязываются к ViewModel. Таким образом View отвечает только за представление, а ViewModel — только за управление состоянием приложения.
MVVM очень широко используется в JavaScript-библиотеке Knockout.js.
Рассмотрим следующую реализацию 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. Проблема в том, что единственный способ проверить логику — это вручную запустить программу и ввести значения для каждого сценария:
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();
}
}
}
На фоне роста спроса на ликвидность в бычьем рынке 2025 года, криптозаймы снова выходят на…
Прокси (proxy), или прокси-сервер — это программа-посредник, которая обеспечивает соединение между пользователем и интернет-ресурсом. Принцип…
Согласитесь, было бы неплохо соединить в одно сайт и приложение для смартфона. Если вы еще…
Повсеместное распространение смартфонов привело к огромному спросу на мобильные игры и приложения. Миллиарды пользователей гаджетов…
В перечне популярных чат-ботов с искусственным интеллектом Google Bard (Gemini) еще не пользуется такой популярностью…
Скрипт (англ. — сценарий), — это небольшая программа, как правило, для веб-интерфейса, выполняющая определенную задачу.…