Model-View-ViewModel (MVVM)
Model-View-ViewModel (skrót MVVM) to architektura aplikacji, której celem jest rozdzielenie logiki biznesowej od warstwy prezentacji. Została opracowana przez firmę Microsoft w 2005 roku z myślą o ułatwieniu tworzenia interfejsów użytkownika w technologii Windows Presentation Foundation (WPF).
Historia
Początkowo koncepcja MVVM była rozwijana jako ewolucja wcześniejszych wzorców architektonicznych, takich jak Model-View-Controller (MVC) oraz Model-View-Presenter (MVP). Dzięki wprowadzeniu wiązania danych (data binding) i wzorca poleceń (Command), MVVM umożliwiło tworzenie interfejsów, które są less code‑behind i bardziej testowalne.
Składowe architektury
- Model – warstwa zawierająca logikę biznesową, zasoby danych oraz reguły walidacji. Model jest niezależny od warstwy prezentacji i może być wykorzystywany w dowolnym kontekście aplikacji.
- View – warstwa odpowiedzialna za prezentację danych użytkownikowi. W MVVM View jest zazwyczaj opisany w języku deklaratywnym, takim jak XAML, i nie zawiera logiki aplikacji.
- ViewModel – pośrednik pomiędzy Modelem a View. Udostępnia właściwości i polecenia (komendy), które są wiązane (bound) do elementów interfejsu w View. ViewModel nie wie nic o konkretnym interfejsie graficznym, co ułatwia testowanie jednostkowe.
Relacje pomiędzy komponentami
W MVVM komunikacja odbywa się głównie w następujący sposób:
- View wiąże się (data binding) z właściwościami i poleceniami udostępnianymi przez ViewModel.
- Gdy użytkownik wywołuje akcję (np. kliknięcie przycisku), ViewModel otrzymuje wywołanie poprzez polecenie i deleguje je do Modelu.
- Model zwraca wyniki (np. pobranie danych z bazy) i powiadamia ViewModel o zmianach, najczęściej za pomocą interfejsu INotifyPropertyChanged.
- ViewModel aktualizuje własne właściwości, co automatycznie odświeża interfejs dzięki mechanizmowi wiązania danych.
Zastosowanie
MVVM jest szczególnie popularny w następujących środowiskach:
- WPF – podstawowa platforma, w której wzorzec został po raz pierwszy wprowadzony.
- Universal Windows Platform (UWP).
- Xamarin.Forms – umożliwia tworzenie aplikacji mobilnych na Android, iOS i Windows.
- Silverlight (historycznie).
- Frameworki JavaScript, takie jak KnockoutJS czy Vue.js, które przyjęły podobne podejście do wiązania danych.
Przykład implementacji w C#
// Model
public class Person
{
public string FirstName { get; set; }
public string LastName { get; set; }
}
// ViewModel
public class PersonViewModel : INotifyPropertyChanged
{
private Person _person;
public PersonViewModel()
{
_person = new Person { FirstName = "Jan", LastName = "Kowalski" };
SaveCommand = new RelayCommand(Save, CanSave);
}
public string FirstName
{
get => _person.FirstName;
set
{
if (_person.FirstName != value)
{
_person.FirstName = value;
OnPropertyChanged(nameof(FirstName));
}
}
}
public string LastName
{
get => _person.LastName;
set
{
if (_person.LastName != value)
{
_person.LastName = value;
OnPropertyChanged(nameof(LastName));
}
}
}
public ICommand SaveCommand { get; }
private void Save()
{
// zapis do bazy, serwisu itp.
}
private bool CanSave() => !string.IsNullOrWhiteSpace(FirstName) && !string.IsNullOrWhiteSpace(LastName);
public event PropertyChangedEventHandler PropertyChanged;
protected void OnPropertyChanged(string propertyName) =>
PropertyChanged?.Invoke(this, new PropertyChangedEventArgs(propertyName));
}
Porównanie z innymi wzorcami architektonicznymi
| Cecha | MVC | MVP | MVVM |
|---|---|---|---|
| Główny element pośredniczący | Controller | Presenter | ViewModel |
| Wiązanie danych (data binding) | Rzadko, wymaga ręcznej synchronizacji | Możliwe, ale nie jest centralnym elementem | Wbudowane, kluczowe |
| Testowalność View | Trudna (logika w Controllerze) | Możliwa (Presenter jest testowalny) | Wysoka – logika w ViewModel, View jest czysto deklaratywna |
| Typowa platforma | Web (ASP.NET, Ruby on Rails) | Desktop (WinForms), Web (GWT) | Desktop i mobilne (.NET, Xamarin) |
Zalety
- Silne wiązanie danych eliminuje konieczność ręcznego odświeżania UI.
- Wyraźny podział odpowiedzialności ułatwia utrzymanie i rozwój aplikacji.
- ViewModel można testować przy użyciu testów jednostkowych bez uruchamiania interfejsu.
- Umożliwia współpracę wielu programistów: jeden zajmuje się UI, drugi logiką biznesową.
Wady
- Wymaga znajomości mechanizmów data binding oraz wzorca Command, co może podnieść krzywą uczenia się.
- W niektórych projektach (np. małe, jednorazowe aplikacje) wprowadza zbędną warstwę abstrakcji.
- Nie każde środowisko UI natywnie wspiera wiązanie danych, co wymusza dodatkowe biblioteki.
Rozwój i wpływ
Po sukcesie w WPF, MVVM stało się inspiracją dla innych platform i frameworków. W Xamarin.Forms oraz .NET MAUI wzorzec jest domyślną architekturą. W świecie JavaScript podobne podejścia przyjęły KnockoutJS, Angular (z komponentami i usługami) oraz Vue.js (reactive data).
Przyszłość
MVVM pozostaje aktualny, zwłaszcza w ekosystemie Microsoft, gdzie rozwijane są kolejne biblioteki wspierające ReactiveUI i Prism. Jego zasady – separacja warstw, deklaratywne UI i testowalny kod – są fundamentem nowoczesnych architektur oprogramowania.
Źródła: dokumentacja Microsoft, 2005 rok publikacji pierwszych wytycznych, literatura z zakresu programowania wzorcowego.