Model - View - Controller (MVC)

Sowohl Prozessoren als auch Softwaretools haben seit Jahren und Jahrzehnten einen deutlich sichtbaren Leistungszuwachs erfahren. In der Methodik der Softwareentwicklung gibt es ebenfalls einen stetigen Fortschritt, der jedoch von den außenstehenden Betrachtern (und Softwarenutzern) weit weniger wahrgenommen wird. Dies bezieht sich dabei weniger auf die Weiterentwicklung von Tools und Frameworks, die ein Programmierer nutzt, sondern vielmehr auf Arbeitssystematiken. Gemeinsames Ziel dieser Systematiken ist es, das Programmieren als solches effizienter zu gestalten.

Es geht heutzutage nicht mehr so sehr darum, das letzte Quentchen Leistung aus einem Stück Code herauszukitzeln; das lohnt den Aufwand nicht. Vielmehr wird beabsichtigt, den Programmacode fehlerärmer, verständlicher, pflegeleichter und leichter erweiterbar zu machen und so dem Programmierer auf lange Sicht Zeit zu sparen, die er wiederum für Leistungsmerkmale seiner Software investieren kann.

Inzwischen steht eine bunte Palette an Programmierparadigmen zur Verfügung, die sich über Jahre und Jahrzehnte als praxisgerecht erwiesen haben. Im Rahmen dieses Zirkulars werden sicherlich noch einige von ihnen thematisiert werden. Diese Programmierprinzipien haben ihren Ursprung in der "professionellen" Softwareentwicklung, und wieweit sie für programmierende Amateurastronomen eine Rolle spielen, ist erst mal dahingestellt. Dennoch kann ein Blick über den Tellerrand ganz interessant sein.

Umgang mit Programmierprinzipien

Programmierprinzipien erleichtern die Arbeit, aber sie wurden nicht in der Absicht geschaffen, den Programmierer zur sklavischen Einhaltung von Richtlinien zu veranlassen. Projekte sind vielgestaltig, und Entscheidungen müssen individuell getroffen werden. Es kann Gründe geben, von der „reinen Lehre“ abzuweichen, solche Regeln nur partiell (z.B. bei kleineren Projekten) oder modifiziert anzuwenden. Die Kreativität des Programmierers ist gefragt, um abzuwägen, welche Programmierparadigmen für das eigene Projekt zweckmäßig sind und bis zu welchem Grad ihre Umsetzung sinnvoll ist.

Model – View - Controller

In der heutigen Ausgabe soll es um das Prinzip des Model – View – Controllers, oder kurz MVC, gehen, einem Verfahren, wie innerhalb einer Softwareapplikation die Logik der Benutzeroberfläche und die der Datenhaltung über den Programmcode sinnvoll aufgeteilt werden kann

Grundprinzip ist, daß beim Model – View – Controller die Logik eines Programms in drei Schichten untergliedert wird:

  • Der View beinhaltet diejenige Logik, die unmittelbar mit der Darstellung von Daten auf der Benutzeroberfläche einerseits und der Dateneingabe des Benutzers andererseits zum Gegenstand hat. Man erkennt schon anhand der Zuständigkeitsdefinition, daß der View keine sonderlich tiefgehende Logik besitzt. Der View kann jedoch eine elementare Validierung von Benutzereingaben vornehmen.Wichtig ist, daß die Klassen oder Module des Views keinerlei funktionale Logik wie Datenverarbeitung, Datenhaltung oder Berechnungen beinhalten. Für diese Logik gibt es wiederum eigene Schichten.
  • Das Model repräsentiert die eigentliche Datenhaltung. Hierbei ist es wichtig hervorzuheben, daß die Struktur von Daten nicht notwendigerweise mit der Art ihrer Darstellung auf der Benutzeroberfläche übereinstimmen muß! Die Daten können in gänzlich anderer Form vorliegen. Die Datenstrukturen im Model sollten keinerlei Merkmale besitzen, die in der Oberflächendarstellung begründet liegen.
  • Die Bedeutung des Controllers ergibt sich aus dem vorstehenden Satz. Der Controller vermittelt zwischen der (logischen) Datenstruktur und der (visuellen) Anzeigeform, die vollständig entkoppelt sind. Anzuzeigende Daten werden gemäß der Oberflächenelemente aufbereitet, während eingegebene Daten wiederum in das Datenmodell konvertiert werden. Der Controller kann quasi als Umstrukturierungsschicht angesehen werden. Zum Controller gehört auch die Verwaltung von Abhängigkeiten in den Darstellungen und den Eingabe- und Konfigurationsmöglichkeiten, die der Anwender zu sehen bekommt (z.B. das Deaktivieren von Schaltflächen, die in bestimmten Programmzuständen aus logischen Gründen nicht zur Verfügung stehen dürfen).

MVC unterstützt eine klare Struktur innerhalb der Software. Änderungen und Erweiterungen an der Software werden leichter durchführbar, da der betroffene Code sich nicht mehr über das gesamte Projekt verteilt.

Ein wichtiger Vorteil von MVC ist die Entkopplung von Datenmodell und Darstellung. Einer der wichtigsten Vorteile ist, daß es auf diese Art und Weise möglich ist, innerhalb des Programms mehrere verschiedenartige Sichten auf den gleichen Datenbestand zu erzeugen.

Die Frage, ob MVC für kleinere Projekte nicht überdimensioniert ist, ist berechtigt. Wie schon oben erwähnt, muß ein Pattern nicht stets in aller Strenge befolgt werden; vielmehr kann es auch sinnvoll sein, es abzuschwächen. Wenn sich z.B. herausstellen sollte, daß der Controller keine umfangreiche Funktionalität hat, so ist es legitim, diesen entweder in das Model oder in den View zu integrieren. Auf alle Fälle hat man seinem Projekt - und das gilt auch bei kleineren! - schon Gutes getan, solange zumindest die Darstellungslogik (View) von der Datenhaltung (Model) entkoppelt ist.

Aktualisierung von Daten

MVC bedingt auch, daß die Oberfläche u.U. auf Änderungen am Datenmodell reagieren muß (Aktualisierung der Anzeige), die von externen Quellen herrühren. Das Mittel der Wahl sind Callbacks. Bei einem Callback registriert sich eine View-Klasse beim Model, um über Datenänderungen benachrichtigt zu werden. Dazu gibt der View eine sogenannte Callback-Methode an das Model bekannt, die im Falle einer Datenänderung aufgerufen wird, den aktuellen Datenstand abfragt und die Anzeige aktualisiert. Die Aktualität der momentan angezeigten Daten ergibt sich auf diesem Wege ganz automatisch.

Wie könnte eine Aktualisierung von externer Quelle aussehen?

  • Datenmodell wird extern aktualisiert.
  • Das Model ruft daraufhin die zuvor registrierte Callback-Funktion auf.
  • Die Callback-Funktion zieht sich ein komplettes Abbild des darzustellenden Models.
  • Die Callback-Funktion bringt den abgerufenen Datenstand zur Anzeige.

Wie sieht im Gegenzug eine Aktualisierung aus, wenn sie vom Programm selbst angestoßen wird?

  • Der Benutzer gibt geänderte Daten ein und aktiviert diese.
  • Der View ruft eine Funktion zum Aktualisieren des Datenmodells auf
  • Das Model ruft daraufhin die zuvor registrierte Callback-Funktion auf.
  • Die Callback-Funktion zieht sich ein komplettes Abbild des darzustellenden Models.
  • Die Callback-Funktion bringt den abgerufenen Datenstand zur Anzeige.

Man sieht: der Weg ist ab dem Aufruf des Callbacks identisch. Es gibt nur einen einzigen Pfad zum Aktualisieren einer Datenansicht, unabhängig davon, ob Daten von externer Quelle verändert werden oder durch Benutzeraktionen. Ganz gleich, welche Teilmenge an Daten zu aktualisieren ist - es wird stets eine exklusive Funktion ausgeführt, die den gesamten Datensatz holt und darstellt. Damit erübrigen sich jegliche Sonderwege und Abhängigkeiten.

MVC hat sich in der Praxis als ein leistungsstarkes Prinzip erwiesen, welches vor allem für Projekte mit größerem Programmieraufwand nützlich ist - vor allem, da es, wie oben schon erwähnt, bei Bedarf auch in abgestufter Form angewandt werden kann.