[ Impressum ]

Zebra-Erweiterungen

www.Rozek.de > Zebra > Tweaks > Investigation
Bisweilen wünscht man sich, Zebra[1]-Klassen hätten zusätzliche Funktionalitäten - oder würde vorhandene Funktionalitäten gerne anpassen bzw. korrigieren. Zwar kann man von den bestehenden Klassen neue Unterklassen ableiten - die Oberklassen lassen sich auf diese Weise aber nicht erweitern.

JavaScript selbst ließe die Erweiterung von "Oberklassen" eigentlich problemlos zu - Zebra hingegen implementiert eine eigene Variante der Objekt-Orientierung und durchbricht dabei die "Prototyp-basierte differentielle Vererbung" von JavaScript.

Auf Grundlage der Untersuchungen zu Zebras Objekt-Orientierung soll an dieser Stelle deshalb beschrieben werden, wie Zebra-Klassen korrekt erweitert werden.

Erweiterung um zusätzliche "statische" Klassen-Methoden

Beginnen wir mit dem einfachsten Fall: Zebra unterscheidet zwischen (im Java-Sinne) "statischen" Klassen-Methoden und sonstigen Objekt-Methoden. Da Klassen-Methoden unmittelbarer Bestandteil einer Klasse sind, kann man neue "statische" Methoden direkt zu einer Klasse hinzufügen - sollte dann aber aufpassen, dass dadurch keine bestehende Methode oder Eigenschaft überschrieben wird:

zebra.ui.WinLayer.getId = function getId () {
return this.ID;
};

Die extend-Methode für zusätzliche Objekt-Methoden

Da Zebra auch das Überladen von Methoden beherrscht, können bestehende (Objekt-)Methoden nicht einfach überschrieben werden: häufig ist die unmittelbar sichtbare Methode nur eine "ProxyMethod", die anhand der Anzahl der beim Aufruf mitgegebenen Argumente an eine von mehreren konkreten Funktionen delegiert.

Glücklicherweise verfügt aber jede Zebra-Klasse über eine (zwar undokumentierte, intern jedoch häufig verwendete) Methode "extend", die diese Besonderheit berücksichtigt und gegebene Funktionen anhand ihres Namens und ihrer Stelligkeit korrekt in die jeweilige Klasse einfügt:

zebra.ui.ImagePan.extend([
function (Candidate, x,y, Width,Height) {
// additional constructor
},


function setImage (Candidate, x,y, Width,Height) {
// additional function
}
]);

Die neu hinzukommenden Funktionen dürfen allerdings in der jeweiligen Kombination von Name und Stelligkeit in der zu erweiternden Klasse noch nicht vorkommen - anderenfalls bricht extend mit einer Fehlermeldung ab.

Die naive Form der Erweiterung...funktioniert nicht!

JavaScript-Programmierer werden vermutlich versucht sein, einfach nur die oberste Klasse in einer Klassen-Hierarchie zu erweitern und dann erwarten, dass sich diese Änderung automatisch auf die davon abgeleiteten Unterklassen auswirkt.

Zebra funktioniert aber anders als JavaScript: leitet man in Zebra von einer bestehenden Oberklasse eine neue Unterklasse ab, werden alle zu diesem Zeitpunkt in der Oberklasse eingetragenen Objekt-Methoden in die neue Unterklasse kopiert. Nachträgliche Änderungen an der Oberklasse wirken sich also nicht auf bereits bestehende Unterklassen aus.

Das folgende kleine JSFiddle zeigt dieses Verhalten am Beispiel der Klasse zebra.layout.Layoutable, die um ein paar Akzessoren erweitert wird:



Bitte beachten Sie insbesondere auch die letzte Ausgabe-Zeile in obigem JSFiddle (vor allem im Vergleich zum folgenden JSFiddle), in welcher angezeigt wird, ob eine der zu zebra.layout.Layoutable neu hinzugefügten Methoden auch in einer der davon abgeleiteten Unterklassen zu finden ist.

Die "smarte" Form der Erweiterung...funktioniert!

Abhilfe verspricht in einigen Fällen die Erweiterung nicht nur der Basisklasse selbst, sondern auch aller ihrer Unterklassen. Sofern die abgeleiteten Klassen Teil der Zebra-Distribution sind, kann der entsprechende Zweig der Klassenhierarchie mit den bereits bekannten Methoden erstellt und alle darin aufgeführten Klassen separat erweitert werden, wie folgendes JSFiddle zeigt:



Auch in diesem JSFiddle ist wieder die letzte ausgegebene Zeile von Interesse, die anzeigt, ob eine der zu zebra.layout.Layoutable neu hinzugefügten Methoden auch in einer der davon abgeleiteten Unterklassen zu finden ist.

Das Verfahren versagt allerdings, sobald eine neu einzutragende Methode in einer der Unterklassen bereits implementiert wurde. Andererseits schützt dieses "Versagen" vor dem versehentlichen Überschreiben existierender Funktionen und ist folglich eher ein hochwillkommenes "Feature" denn ein "Bug".

Viel Spaß damit!

Literaturhinweise

[1]
Andrei Vishneuski
HTML5 Rich UI JavaScript Library
Zebra ist eine noch relativ neue JavaScript-Bibliothek für grafische Benutzeroberflächen in Web-Anwendungen. Diese Seite ist der primäre Anlaufpunkt, wenn Sie sich für Zebra interessieren.