Model-View-ViewModel (MVVM)
Model-View-ViewModel (MVVM) Entwurfsmuster
Das Model-View-ViewModel-Muster (kurz: MVVM) ist ein Architekturmuster, das aus dem MVP-Muster hervorgegangen ist. Es wurde ursprünglich von Microsoft für das Framework WPF (Windows Presentation Foundation) entwickelt und wird heute in vielen modernen UI-Frameworks verwendet – etwa in **MAUI**, **Xamarin**, **Angular**, **Vue.js** und **Blazor**.
Das Ziel ist es, **Benutzeroberfläche, Logik und Daten** konsequent zu trennen und gleichzeitig eine **automatische Synchronisierung** zwischen View und Datenmodell durch **Datenbindung (Data Binding)** zu ermöglichen.
Grundidee
MVVM teilt eine Anwendung in drei Schichten:
| Komponente | Aufgabe |
|---|---|
| Model | Enthält die Daten und Geschäftslogik.
Definiert, wie Daten gespeichert, verarbeitet und validiert werden. |
| View | Stellt die Benutzerschnittstelle dar.
Zeigt die Daten aus dem ViewModel an und sendet Benutzerinteraktionen zurück. |
| ViewModel | Vermittelt zwischen View und Model.
Bereitet Daten auf, stellt Bindungsfelder bereit und reagiert auf Änderungen. |
+--------------+ +----------------+ +--------------+ | View | <-----> | ViewModel | <-----> | Model | | (Anzeige) | Binding| (Logik + State)| | (Daten) | +--------------+ +----------------+ +--------------+
Hauptprinzip
Das ViewModel ist das Bindeglied zwischen der Oberfläche (View) und der Logik (Model). Es stellt **Eigenschaften** und **Befehle (Commands)** bereit, an die die View **gebunden (bound)** wird. Wenn sich der Wert im Model ändert, wird die View automatisch aktualisiert – und umgekehrt.
Ablauf
1. Die **View** bindet ihre Steuerelemente an Eigenschaften und Befehle des ViewModels. 2. Das **ViewModel** verwaltet den Anwendungszustand und kommuniziert mit dem Model. 3. Das **Model** speichert die Daten und führt Geschäftslogik aus. 4. Änderungen werden über das Bindungssystem automatisch synchronisiert.
Beispiel (C# / Pseudocode)
Ein einfaches MVVM-Beispiel in C#-ähnlicher Syntax:
// --- Model ---
public class User {
public string Name { get; set; }
}
// --- ViewModel ---
using System.ComponentModel;
using System.Runtime.CompilerServices;
using System.Windows.Input;
public class UserViewModel : INotifyPropertyChanged {
private User user = new User();
public string Name {
get => user.Name;
set {
user.Name = value;
OnPropertyChanged();
}
}
public ICommand SaveCommand { get; }
public UserViewModel() {
SaveCommand = new RelayCommand(Save);
}
private void Save() {
Console.WriteLine($"Benutzer {Name} wurde gespeichert.");
}
public event PropertyChangedEventHandler PropertyChanged;
protected void OnPropertyChanged([CallerMemberName] string propertyName = null)
=> PropertyChanged?.Invoke(this, new PropertyChangedEventArgs(propertyName));
}
- View (XAML-Beispiel):**
<StackPanel>
<TextBox Text="{Binding Name, UpdateSourceTrigger=PropertyChanged}" />
<Button Content="Speichern" Command="{Binding SaveCommand}" />
</StackPanel>
- Ergebnis:**
Wenn der Benutzer den Text ändert, wird automatisch die `Name`-Eigenschaft im ViewModel aktualisiert. Beim Klick auf den Button wird der `SaveCommand` ausgeführt – ohne dass die View Code-Behind-Logik benötigt.
Vorteile
- **Starke Entkopplung** zwischen Logik und Darstellung
- **Automatische Synchronisierung** durch Datenbindung
- **Hohe Testbarkeit** (ViewModel kann unabhängig von der UI getestet werden)
- **Wiederverwendbarkeit** von ViewModels mit verschiedenen Views
- Ideal für moderne UI-Frameworks mit **Binding-System**
Nachteile
- Erhöhter Initialaufwand durch Implementierung von Bindings und PropertyChanged
- Kann bei großen Projekten komplex werden
- Erfordert Framework-Unterstützung (Bindings, Commands)
Typische Verwendung
- GUI-Frameworks mit Datenbindung:
* **WPF** und **MAUI** (C# / .NET) * **Xamarin.Forms** * **Blazor** * **Angular**, **Vue.js**, **React** (konzeptionell ähnlich)
- Mobile-Apps (Cross-Plattform)
- Client-seitige Webanwendungen (SPAs)
Unterschiede zu MVC und MVP
| Merkmal | MVC | MVP | MVVM |
|---|---|---|---|
| Verbindung Model–View | Möglich | Über Presenter | Über ViewModel mit Bindings |
| Kommunikation | View ↔ Controller ↔ Model | View ↔ Presenter ↔ Model | View ⇄ ViewModel ⇄ Model |
| Datenbindung | Manuell | Teilweise | Automatisch |
| Testbarkeit | Gut | Sehr gut | Sehr gut |
| Framework-Support | Universal | GUI-basiert | Frameworks mit Binding-System |
Beispielhafte Implementierungen
- **C# / .NET:** WPF, UWP, MAUI, Xamarin.Forms
- **JavaScript:** Vue.js, Angular, React (Hooks/State ≈ ViewModel)
- **C++ / Qt:** QML-View mit C++-Backend
- **Swift / iOS:** SwiftUI (State und ViewModel-Konzept)
Vergleich zu ähnlichen Mustern
| Muster | Fokus | Besonderheit |
|---|---|---|
| Model-View-Controller (MVC) Entwurfsmuster | Strikte Trennung von Logik und Darstellung | Controller steuert Model und View |
| Model-View-Presenter (MVP) Entwurfsmuster | Presenter vermittelt aktiv zwischen View und Model | Kein automatisches Binding |
| Model-View-ViewModel (MVVM) | Datenbindung zwischen View und Logik | Automatische Synchronisierung |
Vorteile gegenüber MVP
- Weniger Code durch Binding-Mechanismen
- ViewModel kennt die View nicht direkt
- Verbesserte Wiederverwendbarkeit und Testbarkeit
Nachteile gegenüber MVP
- Bindings sind frameworkabhängig
- Debugging von Bindings oft schwieriger
- Höherer Speicher-Overhead bei komplexen Bindungsstrukturen
Siehe auch
- Model-View-Controller (MVC) Entwurfsmuster
- Model-View-Presenter (MVP) Entwurfsmuster
- Event-Driven Architecture
- Observer-Entwurfsmuster
- Data Binding
- Entwurfsmuster (Softwareentwicklung)
Quellen
- John Gossman (Microsoft): *Introduction to Model-View-ViewModel (2005)*
- Erich Gamma et al.: *Design Patterns – Elements of Reusable Object-Oriented Software*
- Microsoft Docs: Data Binding in WPF
- Martin Fowler: Presentation Model
- Wikipedia: Model–View–ViewModel