![]() |
|
URL dieses Artikels:
zu Ausgabe:
02.2003
Vorsicht ansteckend
Über den Missbrauch von XML in der Softwareentwicklung
von Johannes Link
Die aktuelle Wunderwaffe der Softwareindustrie heißt XML. Kein Programmierwerkzeug, dessen neueste Version nicht mit dem Slogan Jetzt mit noch mehr XML! beworben würde. Als vorsichtige Programmierernatur bringt mich diese Euphorie in einen ernsthaften Zwiespalt: Auf der einen Seite habe ich in mühevollen Jahren die grundlegenden Prinzipien der Modularisierung und anschließend der Objektorientierung für gut befunden und verinnerlicht. Auf der anderen Seite spüre ich das herablassende Lächeln meiner Kollegen, wenn ich zugebe, dass ich noch in Java programmiere und nicht schon längst in XML konfiguriere.
Der Streitpunkt Gewichtige Vorteile der eXtensible Markup Language sind unbestreitbar:
Konfiguration ist jedoch nicht gleich Konfiguration. Bei der Frage, wie viel Programmlogik nicht fest verdrahtet im Quellcode, sondern dynamisch änderbar in XML-Dateien ausgelagert werden sollte, scheiden sich die Geister. Die Verfechter der maximalen Iks-em-ellisierung führen ins Feld, dass
Beginnen wir mit einem (fiktiven) Beispiel, das die Konfiguration einer Webapplikation mit integriertem Datenbankzugriff zeigt: <configuration>So weit ist das alles sehr klar und für jedermann zu verstehen. Die selbe Information hielt man in Vor-XML-Zeiten ebenfalls in Konfigurationsdateien, mit dem einen Unterschied, dass sich jeder Programmierer seine eigene Syntax ausdachte, seinen eigenen Parser schrieb und auch gleich noch eine Miniapplikation für das Erstellen der Konfigurationsdatei. Ein weitere Komplexitätsstufe wird erreicht, sobald man auf Redundanz in den Konfigurationsdaten stößt. Stellen wir uns beispielsweise vor, dass obige Webapplikation für mehrere Hosts und mehrere Datenbanken konfiguriert werden kann, wobei die selbe Datenbank in mehreren Hosts zur Anwendung kommen kann (aber nicht muss). Erweitern wir daher obiges Format um ein Konstrukt zur Referenzierung bestimmter Teilbäume, d.h. wir führen eine Objekt-ID für Datenbanken ein und referenzieren diese in der Host-Konfiguration: <configuration>Ist das nicht wunderbar objektorientiert? Macht das ein Java-Compiler nicht genauso? Ja und nein. Ja, weil natürlich intern tatsächlich Objekt-IDs und Referenzen auf diese IDs verwaltet werden müssen. Nein, weil diese Tatsache für den Programmierer transparent ist, d.h. er muss sich nicht um die IDs kümmern; weder muss er dafür sorgen, dass eindeutige IDs vergeben werden, noch muss er bei der Referenzierung darauf achten, dass er auf eine existierende ID verweist. Er benutzt lediglich das Objekt und basta. Die Einführung von Objekt-IDs hat folgende Auswirkungen: Sowohl der Programmierer der Webapplikation als auch der konfigurierende Anwender müssen beim Einlesen bzw. Erstellen der Konfigurationsdatei darauf achten, dass in den Beide Konsistenzbedingungen können übrigens von einer XML Schema-Definition nicht geleistet werden. Lediglich die Eindeutigkeit von IDs kann mit Hilfe des DTD-Attributs IDREF verifiziert werden, falls eine solche existiert. Auch gibt es keinen leichten Weg, die XML-Spezifikation sinnvoll um solche Referenzen zu erweitern. Der Grund liegt in der Natur des XML-Parsens: Sowohl DOM als auch SAX sind für echte Baumstrukturen ausgelegt und nicht für Vorwärts- oder Rückwärtsreferenzen auf andere Knoten. Übertragen auf Programmiersprachen könnte man sagen: Die Verwaltung von Querbezügen, z.B. zwischen Variablendefinition und Verwendung, ist Aufgabe des Compilers und nicht des Parsers. In Zeiten mächtiger IDEs ausgemerzt geglaubte Krankheiten erleben hierdurch eine Renaissance: Tippfehler und nur unvollständig vorgenommene Umbenennungen führen plötzlich wieder zu Laufzeitfehlern. Die Objekt-ID mit Referenz ist lediglich ein Spezialfall eines Phänomens, das in Sprachen wie XML eine große Rolle spielt: ungesicherte Abhängigkeiten. Eine Abhängigkeit ist dann vorhanden, wenn ein einzelnes Datum nicht für sich selbst steht, sondern als Stellvertreter für etwas, das an anderer Stelle definiert wurde. Ungesichert ist die Abhängigkeit, wenn der Parser die Einhaltung der zugehörigen Konsistenzbedingung nicht verifizieren kann. Ein typisches Beispiel ist die Angabe einer Java-Implementierungsklasse wie in der folgenden Erweiterung unserer Konfigurationsdatei: <database>Dies ist ein Sonderfall des Ansatzes, Komponenten eines Systems nicht im Programmcode fest zu verdrahten, sondern diese Verantwortung der Konfiguration zu überlassen. Die Schwierigkeit liegt darin, dass erst bei Start der Webapplikation tatsächlich bestimmt werden kann, ob die entsprechende Klasse:
Gehen wir noch einen weiteren Schritt in Richtung eierlegende Woll-Milch-Konfiguration. Die Webapplikation soll in Abhängigkeit von der gewählten URI unterschiedliche Programmmodule aufrufen. Wir ergänzen die Konfiguration daher, um einen weiteren Bereich, den wir Landkarte (map) nennen: <configuration>Beginnt die Zugriffs-URI mit app1/, so soll Modul 1 aufgerufen werden, entsprechend Modul 2 bei app2. Zusätzlich wurde ein Default-Modul definiert, das für alle anderen Zugriffs-URIs gelten soll. Die Verwendung von Attributen anstatt zusätzlicher XML-Tags ist hier willkürlich und soll zeigen, dass die Problematik in beiden Fällen die gleiche ist. Auch hier gibt es das Problem ungesicherter Abhängigkeiten, da module1|2|3 Konstanten sind, die wiederum unsere Webapplikation auswerten muss. Das Umbenennen bzw. Hinzufügen eines neuen Moduls im Applikationscode erfordert daher zusätzliche Änderungen in der Konfigurationsdatei. Der neue Komplexitätsgrad an diesem Stück XML ist jedoch, dass eine Änderung der Konfiguration auch eine Änderung der Ablauflogik und des Kontrollflusses zur Folge hat. Und mögliche Änderungen der Programmlogik erfordern - zumindest bei geschäftskritischer Software - die Ausführung systemweiter Regressionstests. Probleme einer XML-zentrierten Entwicklung Fassen wir noch einmal zusammen, was bislang klar geworden sein sollte:
Die Opfer der XMLitis leben übrigens nicht im Verborgenen. Es gibt eine Reihe (sehr) prominenter Vertreter. So leidet bereits XSLT an seiner von Nicht-Programmierern und Gelegenheitsanwendern kaum zu beherrschenden Komplexität und an (immer noch) fehlenden bzw. nicht ausgereiften Werkzeugen zum intuitiven Testen und Debuggen von Transformationen. Nicht ohne Grund hat der ursprünglich so verlockende Ansatz, die Präsentationsebene von Webapplikationen ausschließlich mit XSLT zu implementieren, die serverseitigen Skripte (z.B. JSPs) nicht verdrängen können. Ein weiteres populäres Framework, das nach Meinung des Autors die Grenzen einer sinnvollen XML-Konfiguration deutlich überschritten hat, ist Cocoon2 [1]. In den XML-Dateien von Cocoon-Anwendungen benötigt man jede Menge ungesicherter Abhängigkeiten, mehrere versteckte Programmiersprachen kommen zur Anwendung und es gibt weder eine vollständige DTD noch wirklich hilfreiche Entwicklungstools. Wer einmal versucht hat, die Sitemap einer durchschnittlich komplexen Cocoon-Anwendung zu entwanzen und dabei lediglich auf die Unterstützung durch den XML-Editor angewiesen war, weiß, wovon ich rede. Obwohl es schwierig ist, eine harte Grenze zwischen der sinnvollen und der unsinnigen Verwendung von XML zu ziehen, ist die XML-Sünderliste groß und auch SOAP, EJBs sowie zahlreiche Open Source-Projekte gehören dazu. Ich möchte keineswegs behaupten, dass ein programmiererfahrenes und qualitätsbewusstes Team nicht auch mit XML-zentrierten Frameworks funktionsfähige und stabile Software bauen könnte. Ich glaube jedoch, dass das gleiche Team mit weniger XML, mehr richtiger Programmierung und einer ausgereiften Entwicklungsumgebung spürbar schneller wäre, ganz besonders in der Anpassung eines Systems. Sicherlich fehlschlagen wird der Versuch, die Wartung des Systems in die Hände der Anwender zu legen, d.h. denjenigen, die zwar für den Inhalt verantwortlich sind, aber keine ausreichende programmiertechnische Kompetenz besitzen. Fazit und Tipps Der gegenwärtig verbreitete Missbrauch von XML durch die übermäßige Verschiebung von Programmlogik aus Quellcode in XML-Dateien verstößt gegen Erkenntnisse und Errungenschaften der letzten 30 Jahre Softwareentwicklung:
Die geschilderten Nachteile sind keineswegs die Schuld von XML, sondern treten immer auf, wenn Konfiguration zu Programmierung wird. Die Popularität von XML und die Verfügbarkeit entsprechender Werkzeuge hat lediglich die Umsetzung unguter Praktiken erleichtert. Und natürlich führt an der Konfiguration komplexer Anwendungen kein Weg vorbei. Ein paar Regeln helfen dabei, nicht in die oben genannten Fallen zu tappen:
|
||
|