MVC-Architektur

Da moderne Browser immer leistungsfähiger werden und umfassende Funktionen bieten, ist die Entwicklung vollständiger Webanwendungen in JavaScript nicht nur realisierbar, sondern wird auch immer beliebter. Basierend auf Trends in HTTP Archive ist die Größe des bereitgestellten JavaScript-Codes im Laufe des Jahres um 45% gestiegen.

JS-Übertragungsgröße und JS-Anfragen

Da JavaScript immer beliebter wird, sind unsere clientseitigen Anwendungen wesentlich komplexer als zuvor. Für die Anwendungsentwicklung ist die Zusammenarbeit mehrerer Entwickler erforderlich. Im neuen Zeitalter von Webanwendungen ist es entscheidend, gut zu wartenden und wiederverwendbaren Code zu schreiben. Die Chrome-App mit ihren zahlreichen clientseitigen Funktionen ist da keine Ausnahme.

Designmuster sind wichtig, um verwaltbaren und wiederverwendbaren Code zu schreiben. Ein Muster ist eine wiederverwendbare Lösung, die auf häufig auftretende Probleme im Softwaredesign, in unserem Fall, beim Schreiben von Chrome-Apps, angewendet werden kann. Wir empfehlen Entwicklern, die Anwendung in eine Reihe unabhängiger Komponenten gemäß dem MVC-Muster zu entkoppeln.

In den letzten Jahren wurde eine Reihe von JavaScript MVC-Frameworks entwickelt, z. B. backbone.js, ember.js, AngularJS, Sencha und Kendo UI. Auch wenn sie alle ihre einzigartigen Vorteile haben, folgen alle einer Form von MVC-Muster, um Entwickler zu ermutigen, strukturierteren JavaScript-Code zu schreiben.

MVC-Muster – Übersicht

MVC bietet architektonische Vorteile gegenüber Standard-JavaScript: Es hilft Ihnen, besser organisierten und damit leichter zu wartenden Code zu schreiben. Dieses Muster wurde in mehreren Sprachen und Generationen von Programmierern verwendet und ausgiebig getestet.

MVC setzt sich aus drei Komponenten zusammen:

Modell-View-Controller

Modell

Modell ist der Ort, an dem die Datenobjekte der Anwendung gespeichert werden. Das Modell hat keine Kenntnisse über Ansichten und Controller. Wenn sich ein Modell ändert, werden die Beobachter in der Regel darüber informiert, dass eine Änderung aufgetreten ist.

Um dies besser zu verstehen, verwenden wir die To-do-Listen-App, eine einfache, einseitige Web-App, die Ihre Aufgabenliste verfolgt.

Modell-View-Controller

Das Modell stellt Attribute dar, die mit den einzelnen Aufgabenelementen verknüpft sind, z. B. Beschreibung und Status. Neu erstellte Aufgaben werden in einer Instanz des Modells gespeichert.

Ansehen

In der Ansicht sehen Sie, was die Nutzer sehen und wie sie mit der App interagieren. Die Ansicht besteht aus HTML, CSS, JavaScript und häufig Vorlagen. Dieser Teil Ihrer Chrome-App hat Zugriff auf das DOM.

In der obigen Webanwendung für die Aufgabenliste können Sie beispielsweise eine Ansicht erstellen, in der Ihren Nutzern die Liste der To-do-Elemente ansprechend präsentiert wird. Nutzer können auch ein neues Aufgabenelement über ein Eingabeformat eingeben. Allerdings weiß die Ansicht nicht, wie das Modell aktualisiert werden soll, da dies die Aufgabe des Controllers ist.

Controller

Der Controller ist der Entscheidungsträger und der Kleber zwischen Modell und Ansicht. Der Controller aktualisiert die Ansicht, wenn sich das Modell ändert. Außerdem werden der Ansicht Ereignis-Listener hinzugefügt und das Modell aktualisiert, wenn der Nutzer die Ansicht ändert.

Wenn der Nutzer in der Web-App für die Aufgabenliste prüft, ob ein Element als erledigt markiert ist, wird der Klick an den Controller weitergeleitet. Der Controller ändert das Modell, um das Element als abgeschlossen zu markieren. Wenn die Daten dauerhaft sein müssen, werden auch asynchrone Daten auf dem Server gespeichert. Bei umfangreichen clientseitigen Webanwendungsentwicklung wie Chrome-Apps ist es außerdem von entscheidender Bedeutung, die Daten im lokalen Speicher dauerhaft zu speichern. In diesem Fall speichert der Controller die Daten auch im clientseitigen Speicher wie der FileSystem API.

Es gibt verschiedene Varianten des MVC-Designmusters, z. B. MVP (Model–View–Presenter) und MVVP(Model–View–ViewModel). Selbst beim sogenannten MVC-Designmuster selbst gibt es eine gewisse Abweichung zwischen dem traditionellen MVC-Muster und der modernen Interpretation in verschiedenen Programmiersprachen. In einigen MVC-basierten Frameworks werden beispielsweise Änderungen in den Modellen von der Ansicht beobachtet, während in anderen die Aktualisierung der Ansicht vom Controller durchgeführt wird. Dieser Artikel konzentriert sich nicht auf den Vergleich verschiedener Implementierungen, sondern auf die Trennung von Belangen und deren Bedeutung für das Schreiben moderner Webanwendungen.

Wenn Sie noch mehr erfahren möchten, empfehlen wir das Onlinebuch von Addy Osmani: JavaScript-Designmuster lernen.

Zusammenfassend lässt sich sagen, dass das MVC-Muster Anwendungsentwicklern Modularität bietet und Folgendes ermöglicht:

  • Wiederverwendbarer und erweiterbarer Code.
  • Trennung von Ansichtslogik von Geschäftslogik.
  • Ermöglichen Sie gleichzeitige Arbeit zwischen Entwicklern, die für verschiedene Komponenten (z. B. die UI-Ebene und Kernlogik) verantwortlich sind.
  • Einfachere Pflege.

MVC-Persistenzmuster

Es gibt viele verschiedene Möglichkeiten, Persistenz mit einem MVC-Framework zu implementieren, die jeweils unterschiedliche Vor- und Nachteile haben. Wählen Sie beim Schreiben von Chrome-Apps die Frameworks mit MVC- und Persistenzmustern aus, die sich für Sie natürlich anfühlen und den Anforderungen Ihrer Anwendung entsprechen.

Modell hat seine eigene Persistenz – ActiveRecord-Muster

Das ActiveRecord-Muster ist sowohl in serverseitigen Frameworks wie Ruby on Rails als auch in clientseitigen Frameworks wie Backbone.js und ember.js beliebt. Es übernimmt die Verantwortung für die Persistenz des Modells und wird normalerweise über die JSON API implementiert.

Die Einführung eines separaten Konzepts für die Store and Adapter API ist eine etwas andere Herangehensweise als bei der Verwaltung der Persistenz eines Modells. Speicher, Modell und Adapter (in einigen Frameworks als Proxy bezeichnet) arbeiten Hand für Hand. Ein Speicher ist das Repository, das die geladenen Modelle enthält. Außerdem bietet er Funktionen zum Erstellen, Abfragen und Filtern der darin enthaltenen Modellinstanzen.

Ein Adapter oder ein Proxy empfängt die Anfragen von einem Speicher und wandelt sie in geeignete Aktionen für Ihre persistente Datenschicht (z. B. die JSON API) um. Dies ist beim Design moderner Webanwendungen interessant, da Sie oft mit mehr als einer persistenten Datenschicht wie einem Remoteserver und dem lokalen Speicher eines Browsers interagieren. Chrome-Apps bieten sowohl die Chrome Storage API als auch die HTML5 fileSystem API für clientseitigen Speicher.

Vorteile:

  • Nutzerfreundlich und leicht verständlich.

Nachteile:

  • Schwer zu testen, da die Persistenzebene in die Objekthierarchie „verankert“ ist.
  • Es ist schwierig, dass verschiedene Objekte unterschiedliche nichtflüchtige Speicher verwenden (z. B. FileSystem APIs, indexDB oder serverseitig).
  • Die Wiederverwendung von „Model“ in anderen Anwendungen kann zu Konflikten führen, z. B. die gemeinsame Nutzung einer einzelnen Kundenklasse für zwei verschiedene Ansichten, die jeweils an verschiedenen Orten gespeichert werden sollen.

Controller hat Persistenz

In diesem Muster enthält der Controller einen Verweis sowohl auf das Modell als auch auf einen Datenspeicher und ist dafür verantwortlich, das Modell beizubehalten. Der Controller reagiert auf Lebenszyklusereignisse wie Laden, Speichern und Löschen und gibt Befehle zum Abrufen oder Aktualisieren des Modells an den Datenspeicher aus.

Vorteile:

  • Der Test ist einfacher und der Controller kann an einen fiktiven Datenspeicher übergeben werden, für den Tests geschrieben werden.
  • Dasselbe Modell kann für mehrere Datenspeicher wiederverwendet werden, indem einfach Controller mit unterschiedlichen Datenspeichern erstellt werden.

Nachteile:

  • Die Pflege von Code kann komplexer sein.

AppController hat Persistenz

In einigen Mustern ist ein überwachender Controller für die Navigation zwischen einem MVC und einem anderen verantwortlich. Der AppController entscheidet beispielsweise, dass der Client mit einer Zurück-Schaltfläche von einem Bearbeitungsbildschirm, der MVC-Widgets/-Formate enthält, zu einem Einstellungsbildschirm verschoben wird.

Im AppController-Muster reagiert AppController auf Ereignisse und ändert den aktuellen Bildschirm der Anwendung, indem er einen Aufruf an den Datenspeicher sendet, um alle erforderlichen Modelle zu laden und alle übereinstimmenden Ansichten und Controller für diesen Bildschirm zu erstellen.

Vorteile:

  • Verschiebt die Persistenzebene im Stapel noch weiter nach oben, wo sie leicht geändert werden kann.
  • Verschmutzt Controller niedrigerer Ebene wie ein DatePickerController nicht, die über die Persistenz informiert werden müssen.

Nachteile:

  • Jede Seite bzw. jeder Bildschirm der App erfordert nun eine Menge Boilerplate zum Schreiben oder Aktualisieren: Model, View, Controller, AppController.

MVC ist für die Entwicklung von Chrome-Apps von entscheidender Bedeutung. Wir empfehlen die folgenden CSP-konformen MVC-Frameworks, um sichere und skalierbare Chrome-Apps zu schreiben:

Nützliches Infomaterial

Online

Bücher