Observer-Pattern in AS3.0
So, das 2te Pattern, dass ich hier vorstellen möchte ist das Observer-Pattern.
Beim State-Pattern handelt es sich, wie auch bei dem zuvor vorgestellten State-Pattern, um ein sogenanntes “behavioural Pattern”. Das bedeutet es regelt das Verhalten eurer Applikation. Das Observer-Pattern wird oft auch “Publish-Subscribe” genannt. Mit zu Hilfe nahme des Pattern ist es möglich, das mehrere Objekte sich bei einem Objekt “anmelden” um weiterhin bei Änderungen dieses zweiten Objektes informiert zu werden. Konkret: Es können sich beispielsweise UI-Klassen bei einem Controller anmelden. Dieser kann fortan bei jeder Änderung am Datenmodell die UI-Klassen benachrichtigen, so dass diese sich wiederum updaten und den neuen Inhalt anzeigen können. Der große Vorteil ist, dass mittels des Observer-Patterns ebenfalls eine hohe Austauschbarkeit der UI-Komponenten (der Observer) erlangt wird, da die Applikation (der Controller) nichts über die konkreten Observer weiss, sondern nur weiß, dass diese gerde benachrichtig werden wollen, und wie er diese benachrichtigen kann. Eine hohe Austauschbarkeit wiederum fördert auch eine gute Wartbarkeit und Änderbarkeit - genau das, was von den meisten Applikationen immer erwartet wird.
Vorteile:
- Unabhängigkeit von Observern zur Applikation (Applikation kennt nur das Interface)
- Einfaches broadcasting an alle angemeldeten Observer
- Schnelle Austauschbarkeit von UI-Elementen
Nachteile:
- weiss ich leider keine (vielleicht dass man das mit dem update sauber durchziehen muss, aber das ist ja implizit, sonst muss man das Pattern ja gar nicht verwenden)
Das Pattern:
Das Pattern besteht aus 2 Basisklassen: dem Interface Observer und der Klasse Observable. Das Interface Observer muss später von allen Klassen, die “Beobachter” sein wollen, also die auf Nachrichten von der Applikation hören wollen implementiert werden. Die Klasse Observable ist die Basisklasse für die verteilende Klasse. Sie beinhaltet die Methoden zum hinzufügen und benachrichtigen von Observern.
Die Initialisierung funktioniert beim dem Observer-Pattern nun folgendermaßen:
- erstelle eine Instanz von MyApplication
- erstelle eine Instanz von myObserver (übergebe die Application), so dass der Observer die Application kennt.
- registriere myObserver bei der Application myApplication.addObserver(this);

Jetzt können Mitteilungen in der Application mittels notifyObservers(…) an alle sich bisher registrierten Observer gebroadcasted werden. Vor allem OHNE dass die Application die konkreten Observer kennt!!! Warum ist das so toll? Na ganz einfach. Der Kern eurer Anwendung kennt das UI nicht, daher kann das UI super einfach ausgetauscht werden. das neue UI muss sich nur als Observer registrieren und bekommt wieder alle Änderungen der Applikation mitgeteilt und kann, wenn es möchte darauf reagieren..
Nun noch die Frage, wer triggert ein update? Dieses triggert die Application. Meist jedoch ausgelöst durch ein User-Event, also eine Eingabe in einer der UI-Klassen. Diese wiederum können den Aufruf einfach an die Application weiter delegieren. Diese kann dann z.B. die Datenbank, das Modell o.ä. befragen, updaten… und dann mit den neuen Daten dem UI ein update schicken. - Super, oder?
Beispiel:
So, wem das noch zu abstrakt war, hier ein Beispiel, wie das Ganze real ausschauen könnte. Die Klassen Observer und Observable sind gegeben. Die Konkreten Ausprägungen wähle ich nun jedoch folgendermaßen:
Die broadcastende Instanz ist mein ApplicationController. Dieser ist Sub-Klasse von Observable, er erbt also die Fähigkeit Observer zu sich hinzuzufügen und alle Observer zu benachrichtigen. Meine Observer sind einmal die Navigation (NavigationUI) und die Breadcrumbs (BreadcrumbsUI). Diese bekommen bei der Initialisierung den ApplicationController übergeben. Sie haben also alle ein Attribut myApp. Alle Observer rufen initialisieren sich nun mittels myApp.addObserver(this) sich bei dem Controller.

So, die Applikation ist aufgesetzt. Nun kann der Controller mittels notifyObservers(….) alle registrierten Instanzen benachrichtigen. Merke: Die Kommunikation geht lediglich über die Methode update(), die alle Observer implementieren müssen. Der Conroller kennt also keine Klasse NavigationUI oder BreadcrumbUI, sondern nur das Interface Observable. Somit kann ich jederzeit z.B. die Breadcrumbs weglassen, oder sie durch die Klasse NewBreadCrumbsUI austauschen. Diese muss dann lediglich wieder Observer implementieren und sich bei dem Controller als Observer anmelden - FERTIG!
Download:
So, wer das Ganze selbst erleben möchte, der kann sich hier den Beispiel-Code als Download auf den Rechner laden. (Dieses Beispiel zeigt mittels Traces den Aufruf von einem Update und die Reaktion der UI-Komponenten)
Initialisierungs-Code:
Zum Initialisieren des Beispielcodes könnt ihr folgenden Zeilen verwenden:
----------------------------------------------------------------------
//Initialisierung
var appControler:ApplicationController = new ApplicationController();
var naviUI:NavigationUI = new NavigationUI(appControler);
var breadCrumbsUI:BreadcrumbsUI = new BreadcrumbsUI(appControler);
trace("----------");
//erstes Benachrichtigen der Controller…
appControler.notifyObservers("loaded...");
trace("----------");
//noch ein 2tes Benachrichtigen aller Controller
appControler.notifyObservers("menu changed...");
trace("----------");
----------------------------------------------------------------------
- Viel Spass damit!
September 3rd, 2008 at 10:05
Schöner Artikel, aber leider funktioniert der Download nicht
September 25th, 2008 at 08:53
… so der Download sollte nun wieder funktionieren… da hatte sich ein falscher Ordnername im Pfad eingeschlichen….
Danke fürs “Aufmerksammachen”
Februar 25th, 2009 at 12:57
Wow, das wäre endlich mal eine Lösung für das Variablen-Problem in AS3, jedenfalls wenn ich bei der Hirnverteilung etwas mehr aufgepasst hätte. Wie kann man Dich denn zu einer kleinen Beispiel .fla überreden, hüstel?
Februar 25th, 2009 at 20:39
Hi Aragon,
ich hab doch oben den Beispiel-Code als AS-Klassen mit drin….
http://www.annekewinter.de/_blog/wp-content/uploads/2008/05/observerPattern.zip
Liebe Grüße
Anneke.
Juni 28th, 2009 at 20:41
Hi,
kurzes “Danke” - der Beitrag hats bei mir zu Hause über den Drucker an meine Wand geschafft (habe die seltsame Angewohnheit, mir Sachen die ich lerne direkt über den Monitor an die Wand zu kleben)… bin gerade dabei, mir den Observer als erstes Design Pattern zu verinnerlichen und finde, der Artikel hier leistet gute Aufklärungsarbeit.
Danke & bookmarked, diese Seite.
Thomas.