Model-View-Presenter (MVP)
Model-View-Presenter (MVP) Entwurfsmuster
Das Model-View-Presenter-Muster (kurz: MVP) ist ein Architekturmuster, das aus dem MVC-Muster hervorgegangen ist. Es wird häufig in grafischen Benutzeroberflächen (GUI) eingesetzt, um eine **klare Trennung zwischen Darstellung, Logik und Daten** zu erreichen und die Testbarkeit des Codes zu verbessern.
Grundidee
Wie beim MVC-Muster besteht die Anwendung aus drei Hauptkomponenten:
- Model – enthält die Daten und Geschäftslogik,
- View – ist für die Darstellung und Benutzereingaben zuständig,
- Presenter – vermittelt zwischen View und Model.
Im Gegensatz zu MVC kommuniziert die View **nicht direkt mit dem Model**, sondern **nur über den Presenter**. Der Presenter ist damit die zentrale Steuerkomponente.
+--------------+ +--------------+ +--------------+ | View | <-----> | Presenter | <-----> | Model | | (Anzeige) | | (Logik) | | (Daten) | +--------------+ +--------------+ +--------------+
Komponenten
| Komponente | Aufgabe |
|---|---|
| Model | Enthält Datenstrukturen, Geschäftslogik und Regeln.
Unabhängig von Darstellung oder Benutzerinteraktion. |
| View | Zeigt Daten an und nimmt Benutzereingaben entgegen.
Delegiert alle Aktionen an den Presenter. |
| Presenter | Vermittelt zwischen View und Model.
Reagiert auf Eingaben, ruft Model-Methoden auf und aktualisiert die View. |
Ablauf
1. Die View zeigt Daten an und reagiert auf Benutzeraktionen (z. B. Klicks). 2. Statt direkt das Model zu ändern, ruft sie Methoden des Presenters auf. 3. Der Presenter verarbeitet die Eingabe, ändert das Model und fordert die View zur Aktualisierung auf. 4. Das Model kennt die View nicht – die Kommunikation läuft nur über den Presenter.
Beispiel (C++ Pseudocode)
#include <iostream>
#include <string>
// --- Model ---
class UserModel {
std::string name;
public:
void setName(const std::string& newName) { name = newName; }
std::string getName() const { return name; }
};
// --- View Interface ---
class IUserView {
public:
virtual void displayUser(const std::string& name) = 0;
virtual ~IUserView() = default;
};
// --- Presenter ---
class UserPresenter {
IUserView& view;
UserModel& model;
public:
UserPresenter(IUserView& v, UserModel& m) : view(v), model(m) {}
void onUserInput(const std::string& input) {
model.setName(input);
view.displayUser(model.getName());
}
};
// --- Concrete View ---
class ConsoleUserView : public IUserView {
public:
void displayUser(const std::string& name) override {
std::cout << "Benutzername: " << name << std::endl;
}
};
// --- main ---
int main() {
UserModel model;
ConsoleUserView view;
UserPresenter presenter(view, model);
presenter.onUserInput("Alice");
}
- Ausgabe:**
Benutzername: Alice
Unterschiede zu MVC
| Merkmal | MVC | MVP |
|---|---|---|
| Kommunikation | View ↔ Controller ↔ Model | View ↔ Presenter ↔ Model |
| Verbindung Model–View | Möglich | Strikt getrennt |
| Hauptsteuerung | Controller | Presenter |
| Datenfluss | Teilweise bidirektional | Meist Presenter-gesteuert |
| Testbarkeit | Gut | Sehr gut (Presenter leicht isolierbar) |
Varianten
- **Passive View:**
Die View ist vollständig passiv – sie enthält keine Logik und wird ausschließlich durch den Presenter aktualisiert. → Vorteil: hohe Testbarkeit.
- **Supervising Controller:**
Die View kann einfache Datenbindungen selbst verwalten, während komplexe Logik im Presenter bleibt. → Kompromiss zwischen Einfachheit und Flexibilität.
Vorteile
- Strikte Trennung zwischen Logik und Darstellung
- Hohe Wiederverwendbarkeit und Testbarkeit (Presenter kann ohne UI getestet werden)
- Keine direkte Abhängigkeit der View vom Model
- Gut geeignet für GUI-Frameworks mit klaren Schnittstellen (z. B. Android, Qt, WinForms)
Nachteile
- Mehr Boilerplate-Code durch Interfaces und Zwischenschichten
- Erhöhter Kommunikationsaufwand zwischen Komponenten
- Bei zu viel Logik im Presenter kann dieser überladen werden
Typische Einsatzgebiete
- GUI-Anwendungen (Desktop oder Mobile)
- Systeme mit klarer Trennung von Frontend- und Logikschicht
- Anwendungen mit Fokus auf Unit-Testing und Mock-Views
(z. B. Android-Apps mit Test-Frameworks)
Vergleich mit ähnlichen Mustern
| Muster | Hauptidee | Kommunikation |
|---|---|---|
| Model-View-Controller (MVC) Entwurfsmuster | Controller reagiert auf Benutzeraktionen | View ↔ Controller ↔ Model |
| Model-View-Presenter (MVP) | Presenter verwaltet Logik und Aktualisierung der View | View ↔ Presenter ↔ Model |
| Model-View-ViewModel (MVVM) Entwurfsmuster | View ist über Datenbindung an ViewModel gekoppelt | View ⇄ ViewModel ⇄ Model |
Beispielhafte Frameworks
- **Android:** Activity/Fragment als View, Presenter als Logik (z. B. mit „Moxy“ oder „Mosby“ Frameworks)
- **WinForms / WPF (C#):** Presenter als Vermittler zwischen GUI und Datenmodell
- **Qt (C++):** Presenter kann zwischen QML-View und C++-Backend vermitteln
Siehe auch
- Model-View-Controller (MVC) Entwurfsmuster
- Model-View-ViewModel (MVVM) Entwurfsmuster
- Presentation-Abstraction-Control (PAC) Muster
- Event-Driven Architecture
- Entwurfsmuster (Softwareentwicklung)
Quellen
- Martin Fowler: *GUI Architectures* (2006)
- Erich Gamma et al.: *Design Patterns – Elements of Reusable Object-Oriented Software*
- Martin Fowler: UI Architectures
- Wikipedia: Model–View–Presenter
- Refactoring.Guru: MVP Pattern