Logic-Data-View-Controller-Service-Paradigma: Unterschied zwischen den Versionen

aus GlossarWiki, der Glossar-Datenbank der Fachhochschule Augsburg
Keine Bearbeitungszusammenfassung
Keine Bearbeitungszusammenfassung
Zeile 95: Zeile 95:
denen sie kommunizieren sollen. Dies kann auf mehrere Arten geschehen.
denen sie kommunizieren sollen. Dies kann auf mehrere Arten geschehen.


Zum Beipiel kann es [[Singelton]]-Klassen geben, die alle Komponenten enthalten und
Zum Beipiel kann es [[Singleton]]-Klassen geben, die alle Komponenten enthalten und
über die die einzelnen Komponenten die jeweils benötigten Kommunikatonspartner ermitteln.
über die die einzelnen Komponenten die jeweils benötigten Kommunikatonspartner ermitteln.
Dieses Vorgehen hat allerdings den Nachteil, dass die Singelton-Klassen im Prinzip  
Dieses Vorgehen hat allerdings den Nachteil, dass die Singleton-Klassen im Prinzip  
globalen Variablen entsprechen: Man sieht ihnen nicht an, welche Klassen darauf zugreifen.  
globalen Variablen entsprechen: Man sieht ihnen nicht an, welche Klassen darauf zugreifen.  
Daher sollte man auf Singleton-Klassen besser verzichten.
Daher sollte man auf Singleton-Klassen besser verzichten.

Version vom 23. Februar 2011, 18:43 Uhr

Definition

Das Logic-Data-View-Controller-Services-Paradigma oder -Pattern, kurz LDVCS, bezeichnet ein Architekturmuster zur Trennung einer Anwendung in drei separate Einheiten: Logic (Logik), Data (Daten), View (Darstellung), Controller (Steuerung) und Service (Service).

Konzept

gerahmt||rechts|LDVCS-Prozess Dieses Paradigma ist eine Verfeinerung des Model-View-Controller-Services-Paradigmas (MVCS-Paradigma).

Die Modellkomponente des MVCS-Paradigmas übernimmt normalerweise zwei Aufgaben: Die Speicherung der Anwendungsdaten und die Realisierung der Anwendungslogik. (Manchmal übernimmt auch der Controller die Realisierung der Anwendungslogik.) Im LDVCS-Paradigma wird die Modellkomponente in zwei Komponenten aufgeteilt: eine Datenkomponente (Data) und eine Logikkomponente (Logic). Der Controller darf nun nicht mehr direkt schreibend auf die Datenkomponente zugreifen. Dies ist jetzt die Aufgabe der Logikkomponenten (und evtl. der Servicekomponente).

Der LDVCS-Prozess

Beispiel Jump 'n' Run

In einem Jump-'n'-Run-Spiel werden Daten (Data) über die Spielfigur (Position, Laufrichtung, Geschwindigkeit ...), die Gegner, die Gegenstände etc. gespeichert.

Die View' visualisiert die Elemente des Spiels mit Hilfe von Bildern und Animationen (Walk cyles etc.). Jede Änderung an den Daten hat, sofern sie sich im für den Spieler sichtbaren Bereich befindet, eine Anpassung der View zur Folge.

Der Spieler steuert die Spielfigur mit Hilfe der Tastatur. Jeder Tastendruck wird vom Controller analysiert und zur Manipulation der Spielfigur an die Logik-Komponente (Logic) weitergeleitet.

Man beachte, dass die Logik-Komponente i. Allg. aktiv sein kann: Sie kann die Daten selbstständig, d.h. auch ohne Manipultation durch den Controller verändern. Beispielsweise werden die gegnerischen Figuren, sofern es welche gibt, direkt von der Logik-Komponente gesteuert.

Mit Hilfe einer Service-Komponente (Service) kann das Spiel zu einem Multiuser-Spiel erweitert werden. Die Service-Komponente hat dann zwei Aufgaben:

  1. Die Position des Avatars (d.h. der eigenen Spielfigur) an einen zentralen Server zu übertragen.
  2. Die Postition anderer Spielfiguren und möglicher Gegner vom zentralen Server zu holen und in die eigene Datenkomponente zu schreiben.

Eine weitere typische Aufgabe der Service-Komponente ist es, die Daten-Komponente bei Programmstart zu initialisieren. Zu diesem Zweck sollten die Service-Komponente eine Initialisierungsmethode implementieren, die vom Hauptprogramm direkt aufgerufen wird, nachdem die Daten- und die Service-Komponete erzeugt wurden.

Modularität

Der große Vorteil des LDVCS-Paradigmas ist die Modularität. Das PrinzipSeparation of Concerns“ wird hierbei bachtet: Jede Aufgabe wird von einer eigenen Komponente bearbeitet.

Ein Jump'n'Run-Spiel beispielsweise, das derartig modular aufgebaut ist, kann sehr leicht an neue Gegebenheiten angepasst werden. Jede der folgenden Änderungen hat lediglich Auswirkungen auf eine der fünf Komponenten:

  1. Änderung der Darstellung (d.h. der View): Die View kann jederzeit durch neue Skins aktualisiert werden. Es ist auch möglich, die 2D-Ansicht des Spiels durch eine Pseudo-3D-Ansicht zu ersetzen. Bei einem Multiuser-Spiel hat sowieso jeder Spieler seine eigene Sicht auf die Szenerie.
  2. Änderung der Spielsteuerung (d.h. des Controllers): Anstelle einer Steuerung der Spielfigur durch die Tastatur kann beispielsweise eine Steuerung der Spielfigur durch eine WiiMote erfolgen.
  3. Änderung der Spiellogik (d.h. der Logikkomponente): Die KI-Engine zur Steuerung der Gegener kann beispielsweise durch eine bessere Engine ersetzt werden.
  4. Änderung der Dateninitialisierung (d.h. der Service-Komponente): Wenn die Dateninitialisierung künfig beispielsweise nicht mehr über XML, sondern über SQL erfolgen soll, muss ledichlich die entsprechende Service-Komponente ausgetauscht werden.
  5. Änderung des Spielservers (d.h. der Service-Komponente): Es ist jederzeit möglich, ein Multi-User-Spiel über einen anderen Server (mit einer anderen Architektur) laufen zulassen.

Auch die Datenkomponente kann ausgetauscht werden, wenn z.B. andere Datenstrukturen zur Speicherung der Daten eingesetzt werden sollen. Es ist auch möglich, einer Datenkomponente Filter vorzuschalten (vgl. Aspektorientierte Programmierung). Zum Beispiel kann auf diese Weise ine Login-Mechanismus realisiert werden: Der Zugriff auf bestimmte Daten wird erst dann erlaubt, wenn ein Login-Vorgang erfolgreich abgschlossen wurde.

Verfeinerung des LDVCS-Prozesses

Genauso wie der MVC-Prozess und der MVCS-Prozess kann auch der LDVCS-Prozess verfeinert werden. Auch hier bietet sich die Aufteilung in Kernawendungen (Domains) und eine Rahmenanwendung (Frame) an, die den Zugang zu den Kernanwendungen steuert. In diesem Fall gibt es mehrere relativ unabhängige LDVCS-Prozesse: Die Rahmenkomponente darf auf zugehörigen Kernkomponenten zugreifen. Der umgekehrte Weg sollte allerdings vermieden werden, damit die Kernanwendungen problemlos in andere Umgebungen integriert werden können.

gerahmt|links|LDVCS-Prozess 2 (mit Trennung in Frame und Domain)  

Beispiel „Spiel mit Highscore-Verwaltung“

Wenn man ein „Spiel mit Highscore-Verwaltung“ realisieren möchte, sollte man zwei unanhängige Kernanwendungen schreiben. Das Spiel selbst und eine spielunabhängige Highscore-Verwaltung. Die Rahmenanwendung verknüpft diese beiden Anwendungen.

Die Rahmenanwendung liest beispielsweise bei Spielende die erreichten Punkte aus dem Spielmodell aus und leitet diese an das Highscore-Modell weiter. Eine weitere Möglichkeit wäre, dass die Rahmenanwendung über die Highscore-Anwendung ermittelt, ob der Spieler schon mindestens fünf Level erfolgreich gespielt hat. Nur in diesem Fall gewährt sie den Zugang zum Trainingsmodus des Spiels.

Implementierung

Folgendes Klassendiagramm zeigt, wie eine Anwendung, die gemäß dem LDVCS-Paradigma implementiert wird, prinzipiell aufgebaut sein kann.

left|miniatur|977722px|LDVCS-Klassendiagramm

Für jeder der fünf Komponenten (Logic, Data, Model, View, Controller) gibt es ein Interface, das die Methoden und Attribute deklariert, die diese Komponente unterstützt, sowie eine Klasse, die das zugehörige Interface implementiert. Durch die Verwendung von Interfaces ist es ganz einfach, eine Komponentenimplementierung durch eine andere zu ersetzen.

Jedes Interface mit Ausnahme des Interfaces <cod>I_Data defniert Beziehungen zu anderen LDVCS-Klassen. Die Data-Komponente kommuniziert mit den anderen Komponenten über Signale (siehe Observer-Pattern).

Man beachte, dass jede andere Komponente alle Komponenten „kennt“, mit denen sie (evtl.) kommunizieren muss. Die zugehörigen Part-of-Attribute können als Add-only-Attribute implementiert werden. Das heißt, es ist nicht notwendig, dass die Werte dieser Attribute nach der Initialisierung noch einmal von einer anderen Komponente gelesen werden müssten. Ein wichtiger Aspekt der Implementierung ist daher die Initialisierung der Komponenten. Insbersondere müssen die Komponenten die anderen Komponenten kennen, mit denen sie kommunizieren sollen. Dies kann auf mehrere Arten geschehen.

Zum Beipiel kann es Singleton-Klassen geben, die alle Komponenten enthalten und über die die einzelnen Komponenten die jeweils benötigten Kommunikatonspartner ermitteln. Dieses Vorgehen hat allerdings den Nachteil, dass die Singleton-Klassen im Prinzip globalen Variablen entsprechen: Man sieht ihnen nicht an, welche Klassen darauf zugreifen. Daher sollte man auf Singleton-Klassen besser verzichten.

Eine weitere Möglichkeit wäre, alle Komponente über Signale miteinander kommunizieren zu lassen. Dann müssten die Komponenten sich gegenseitig gar nicht kennen (sofern alle wichtigen Informationen direkt in den Signalen übermittelt werden). Hier müssten bei der Initialisierung die Signaler und die Observer geeignet miteinander vernetzt werden. Allerdings sind die Data-Komponentne und die Logik-Komponente i. Allg. eng miteinander verknüpft, da die Logik-Komponenten sowohl lesend, als auch schreiben auf die Date-Komponente zugreift. Hier ensteht durch das Observerpattern ein unnötiger Overhead.

Eine letzte Möglichkeit ist es, die benötigten Komponenten per Dependency Injection den anderen Komponenten bekannt zu geben.

Beispiele

Beispielsimplementierungen, die das LDVCS-Prinzip umsetzen, finden Sie in den ActionScript-Tutorien:

Darüber hinaus gibt es für Flex 4, Flash 11 (CS5) und Flash 10 (CS4) Rahmen-Implementierungen, die Sie als Basis für die Implementierung eigener Anwendungen verwenden können:

Umsetzung des Klassendiagramms in Flex 4 [1] (SVN-Repository)
Umsetzung des Klassendiagramms in Flash 11 (CS5) [2] (SVN-Repository)
Umsetzung des Klassendiagramms in Flash 10 (CS4) [3] (SVN-Repository)

In den obigen Beispielen wurden alle im obigen Diagramm definierten Klassen und Beziehungen implementiert, jedoch keine weitere Funktionalität.

Wenn Sie eine eigene Anwendung auf Basis des LVCDS-Paradigmas implementieren wollen, sollten Sie sich die gewünschte Rahmen-Anwendung per Subclipse in Eclipse (bzw. Flash Builder 4) laden. Heben Sie anschließend die Verknüpfung zum SVN-Repository auf:

  • In Eclipse/Flash Builder: Klick mit rechter Maustaste auf das Projekt → Team → Disconnect → Also delete the SVN meta information from the file system. → Ja/Yes

Nun können Sie die Klassen und Pakete (mittels Refactoring) umbenennen. Ersetzen Sie am Besten in allen generischen Namen der Art Domain... den Begriff Domain durch den Namen Ihrer Anwendung. Und ersetzen Sie das Paket domain durch ein Paket mit dem (kleingeschriebenen) Namen Ihrer Anwendung.


Quellen

Siehe auch


Dieser Artikel ist GlossarWiki-konform.