Patterns in der Softwarearchitektur: Model-View-Controller
![](https://heise.cloudimg.io/width/700/q75.png-lossy-75.webp-lossy-75.foil1/_www-heise-de_/imgs/18/4/1/4/0/6/0/8/shutterstock_1185914659-3a9ae8c8bc4c2728.jpeg)
(Bild: Blackboard/Shutterstock.com)
Der Model-View-Controller ist eines der klassischen Architekturmuster für flexible Mensch-Maschine-Schnittstellen.
Patterns sind eine wichtige Abstraktion in der modernen Softwareentwicklung und Softwarearchitektur. Sie bieten eine klar definierte Terminologie, eine saubere Dokumentation und das Lernen von den Besten.Der Model-View-Controller (MVC) ist eines der klassischen Architekturmuster aus dem Buch "Pattern-Oriented Software Architecture, Volume 1 [1]". Es richtet sich an interaktive Anwendungen mit einer flexiblen Mensch-Maschine-Schnittstelle.
Das MVC unterteilt die Programmlogik einer Bedienoberfläche in die einzelnen Komponenten Model, View und Controller. Das Model verwaltet die Daten und Regeln der Anwendung. Die View stellt die Daten dar, und der Controller interagiert mit dem Benutzer.
![](https://heise.cloudimg.io/width/696/q85.png-lossy-85.webp-lossy-85.foil1/_www-heise-de_/imgs/18/4/1/4/0/6/0/8/MVC-6f2741c5f3726f0b.png)
Model-View-Controller
Zweck
- Benutzeroberflächen müssen häufig geändert werden,
- unterschiedliche Benutzeroberflächen müssen unterstützt werden und
- das Datenmodell ist stabil.
Lösung
- Die Anwendung wird in die Komponenten Model (Datenmodell), View (Ausgabekomponenten) und Controller (Eingabekomponenten) unterteilt und
- mehrere Ausgabekomponenten können das gleiche Datenmodell verwenden.
Struktur
![](https://heise.cloudimg.io/width/360/q85.png-lossy-85.webp-lossy-85.foil1/_www-heise-de_/imgs/18/4/1/4/0/6/0/8/ModelViewControler-adb82abbce3c9de5.png)
![](https://heise.cloudimg.io/width/696/q85.png-lossy-85.webp-lossy-85.foil1/_www-heise-de_/imgs/18/4/1/4/0/6/0/8/ModelViewControllerCRC-8b813fcd8c89cb46.png)
Model
- ist die zentrale Komponente des Musters,
- enthält die Daten (und die Geschäftslogik) und
- ist unabhängig von
View
undController.
View
- ist für die Darstellung der Daten und die Benutzerinteraktion verantwortlich
- Beobachtet das
Model
und - eine
View
ist mit einemController
verbunden, um dasModel
zu manipulieren.
Controller
- verwaltet eine oder mehrere Views
- nimmt Benutzerinteraktionen entgegen und bereitet sie für das
Model
oder View auf, - beobachtet das
Model
und - implementiert die Aktualisierungslogik.
Es gibt zwei interessante Aspekte der MVC: Initialisierung und Benutzereingabe:
Initialisierung
Die folgenden Schritte finden während der Initialisierung des MVC statt:
- Das Modell wird erstellt und seine Daten werden initialisiert.
- Die Views werden erstellt und beobachten das Modell.
- Der Controller wird erstellt und erhält Verweise auf das Model und die Views.
- Der Controller beobachtet das Model.
- Die Anwendung beginnt mit der Ereignisverarbeitung.
Benutzereingabe
Bei einem Benutzerereignis finden die folgenden Schritte statt:
- Der Controller nimmt die Benutzereingaben entgegen, verarbeitet sie und triggert das Modell.
- Das Modell ändert seine internen Daten.
- Das Modell benachrichtigt alle Views und Controller über die Änderung der internen Daten.
- Die Views und Controller aktualisieren sich selbst. Beispiel: Wenn die PIN an einem Geldautomaten zum dritten Mal falsch eingegeben wird, kann das bedeuten: Auf dem Display wird angezeigt, dass das Konto gesperrt ist. Der Geldautomat beschlagnahmt die Debitkarte.
- Der Controller fährt fort, Ereignisse zu verarbeiten.
Beispiel
Das folgende Programm mvc.cpp
wendet MVC an.
// mvc.cpp
#include <iostream>
#include <string>
#include <unordered_map>
class DefectModel {
public: // (5)
mutable std::unordered_map<std::string, std::string>
defects_ = { {"XYZ" , "File doesn't get deleted."},
{"XAB" , "Registry doesn't get created."},
{"ABC" , "Wrong title get displayed."} };
std::string getDefectComponent(const std::string& component)
const {
return defects_[component];
}
int getSummary() const {
return defects_.size();
}
std::unordered_map<std::string, std::string> getAllDefects()
const {
return defects_;
}
};
class DefectView {
public:
void showSummary(int num) const {
std::cout << "There are " + std::to_string(num) +
" defects in total!\n";
}
void showDefectComponent(const std::string& defect) const {
std::cout << "Defect of component: " + defect + '\n';
}
void showDefectList(const std::unordered_map<std::string,
std::string>& defects) const {
for (const auto& p: defects) {
std::cout << "(" + p.first + ", " + p.second + ")\n";
}
}
};
class DefectController {
const DefectModel& defectModel;
const DefectView& defectView;
public:
DefectController(const DefectModel& defModel,
const DefectView& defView):
defectModel{defModel}, defectView{defView} { }
void showDefectComponent(const std::string& component)
const {
defectView.showDefectComponent(
defectModel.getDefectComponent(component)); // (6)
}
void showDefectSummary() const {
defectView.showSummary(defectModel.getSummary()); // (7)
}
void showDefectList() const {
defectView.showDefectList(
defectModel.getAllDefects()); // (8)
}
};
int main() {
std::cout << '\n';
DefectModel defectModel;
DefectView defectView;
DefectController defectController(defectModel,
defectView); // (1)
defectController.showDefectComponent("ABC"); // (2)
std::cout << '\n';
defectController.showDefectSummary(); // (3)
std::cout << '\n';
defectController.showDefectList(); // (4)
std::cout << '\n';
}
Der Controller holt sich sein Modell und seine Ansicht in seinem Konstruktor (1) und zeigt seine Fehlerliste defects_
(5) auf drei Arten an (2 - 4). Der Controller stößt jeden Aufruf in der main
Funktion an und verwendet seine Views, um die vom Modell vorgegebenen Daten anzuzeigen (6 - 8).
Der folgende Screenshot zeigt die Ausgabe des Programms:
![](https://heise.cloudimg.io/width/581/q85.png-lossy-85.webp-lossy-85.foil1/_www-heise-de_/imgs/18/4/1/4/0/6/0/8/mvcExample-c181b558eb9d887e.png)
Variation
Presentation-Abstraction-Control [2] ist ein weiteres Muster aus dem Buch "Pattern-Oriented Software Architecture, Volume 1 [3] und ähnelt dem MVC. Es verwendet eine hierarchische Struktur von Agenten, wobei jeder Agent aus der Präsentation, der Abstraktion (Modell) und der Datenkontrolle besteht. Die Agenten kommunizieren miteinander mithilfe des Controllers.
Vor- und Nachteile
Vorteile
- Separation of concern: Das Modell ist strikt vom Controller und den Views getrennt. Daher können viele Views oder Controller gleichzeitig unterstützt und zur Laufzeit geändert werden.
- Die Views sind synchronisiert, da sie zur gleichen Zeit aktualisiert werden.
Nachteile
- MVC kann für eine kleine Mensch-Maschine-Schnittstelle zu komplex und überladen sein.
- Eine Änderung am Modell kann eine Kaskade von Operationen an den abhängigen Views und Controllern auslösen.
- Der View und der Controller sind stark gekoppelt. Eine Änderung an einem von ihnen kann den anderen zerstören.
Wie geht's weiter?
Ereignisgesteuerte Anwendungen wie GUIs oder Server verwenden oft das Architekturmuster Reactor. Ein Reactor kann mehrere Anfragen gleichzeitig annehmen und sie auf verschiedene Handler verteilen. (rme [4])
URL dieses Artikels:
https://www.heise.de/-8956787
Links in diesem Artikel:
[1] https://en.wikipedia.org/wiki/Pattern-Oriented_Software_Architecture
[2] https://en.wikipedia.org/wiki/Presentation%E2%80%93abstraction%E2%80%93control
[3] https://en.wikipedia.org/wiki/Pattern-Oriented_Software_Architecture
[4] mailto:rme@ix.de
Copyright © 2023 Heise Medien