Vor einem Jahr wurde das Drupal-Release 7 offiziell freigegeben. Wie steht Drupal nach diesem Jahr da? Und wie könnten die Perspektiven für Drupal in den kommenden Jahren aussehen?
Von außen
Trotz großer Bemühungen, waren lange Zeit wichtige Zusatzmodule von Drupal 7 nicht verfügbar. Die Anzahl von Drupal 7-Installationen kam deshalb erst im zweiten Halbjahr 2011 in Schwung. Seitdem ist die Anzahl von Installationen stark gestiegen. Das Wachstum von Drupal mit der dahinter stehenden Firma Acquia geht also weiter. Weiteres Eindringen in den lukrativen Unternehmensmarkt steht auf der Agenda. Daneben haben die Arbeiten an Drupal 8 begonnen; eine Reihe wichtiger Verbesserungen ist für das nächste Release vorgesehen. Alles in allem sieht die Situation doch gut aus - oder?
Von innen
Trotz der äußerlich positiven Eindrücke, läuft nicht alles rund bei Drupal. Einige Neuerungen von Drupal 7 waren meiner Meinung nach weniger glücklich. Auch zeigten einige Äußerungen in der Drupal Community, dass es im Gebälk stellenweise knirscht (siehe zum Beispiel hier oder hier). Das starke Wachstum verläuft nicht immer glatt.
Das neue Render API ist gewöhnungsbedürftig. Oberflächennahe Codierer müssen etwas mehr in den Drupal Code einsteigen, um zu wissen, was Drupal am Ende der Verarbeitung liefert.
Die Datenbankzugriffsschicht wurde auf Objektorientierung umgestellt; sie ähnelt PHP PDO. Allerdings wurden im Kern nicht alle Module durchgehend auf das neue API umgestellt. Die Dokumentation der neuen Datenbankschnittstelle war auf einfache Fälle ausgelegt; wer aufwändigere Fälle hatte, musste tiefer einsteigen, und gegebenenfalls im Quellcode recherchieren. Allerdings frage ich mich, ob Drupal mit diesem selbstentwickelten Datenbank API den richtigen Weg beschritten hat. Wäre es nicht besser gewesen, gleich auf eine etablierte Lösung wie etwa Doctrine zurückzugreifen?
SimpleTests wurden in den Drupal-Kern aufgenommen. Damit sollte die Nutzung vereinfacht und die Testabdeckung für die Module wesentlich gesteigert werden. Da allerdings beim Umstieg von Drupal 6 auf 7 auch die MySQL-Datenbank-Engine von MyISAM nach InnoDB geändert wurde, und solche Tabellen bei Tests aufwändig neu angelegt werden, dauern Tests - ohne besondere Zusatzmaßnahmen - wesentlich länger als vorher. Dabei gehört es bei agilen Testansätzen zu den wichtigsten Zielen, die Hemmschwellen möglichst niedrig zu halten, und schnelle Testergebnisse zu erhalten. Dieses neue Feature hat sich aus meiner Sicht also als völlig kontraproduktiv erwiesen.
Das Shop-SystemUbercart war in die Jahre gekommen. Mit Drupal Commerce wurde ein neuer Anlauf genommen, ein adäquates Shop-Modul zusammenzubauen, das die neuen Möglichkeiten von Drupal nutzt. Die ersten Releases von Drupal Commerce wurden im Herbst fertiggestellt. Mal sehen, wie lange es dauert, bis sich dieses Shopsystem mit hinreichendem Reifegrad in nicht-englischsprachigen Ländern mit jeweils unterschiedlichen gesetzlichen Rahmenbedingungen am Markt platzieren kann.
Einige Community-Mitglieder bekundeten ihren Frust. Sogar der Begriff Burn-out machte die Runde. Die Wartung einzelner Module war zu aufwändig. Gleichzeitig wurde aber klar, dass das ein oder andere Kern-Modul in den vergangenen Jahren fast ohne Wartung weiter mitgeschleppt wurde; schwer wartbarer Legacy Code hatte sich angesammelt. Außenstehende mag das verwundern. Schließlich nimmt Drupal für sich in Anspruch, bei neuen Releases nicht unbedingt Rücksicht auf bestehenden APIs zu nehmen. Damit sollte doch gerade gewährleistet werden, dass alter Code nicht unnötig mitgeschleppt wird.
Ein weiterer Punkt stimmt mich bedenklich: Objektorientierung wird bei Drupal nur in Ansätzen genutzt, bei weitem noch nicht durchgängig. Dabei gibt es PHP 5.3 bereits seit zweieinhalb Jahren. Seit PHP 5.3 stehen ausreichende objektorientierte Möglichkeiten in PHP zur Verfügung; insbesondere die Testbarkeit des Programm-Codes steigt dadurch deutlich. Andere CMS-Systeme oder Frameworks sind bereits auf den Zug aufgesprungen oder dabei, aufzuspringen - siehe zum Beispiel Symfony2, Typo3 mit FLOW3 oder Magento mit dem Zend Framework. Drupal dagegen versucht nur einige zaghafte Ansätze. So sollen etwa zwei Symfony2-Komponenten in Drupal 8 verwendet werden.
Bislang jedenfalls finden sich im Kern immer noch Funktionen mit hundert, zweihundert oder mehr Zeilen. Manches ist noch hart kodiert, die Module sind eng gekoppelt. Unter solchen Umständen ist es nicht verwunderlich, dass sich die vorhandenen SimpleTests auf funktionale Web-Tests konzentrieren. An feingranulare Unit-Tests ist kaum zu denken. Stabilität erfährt der Programm-Code vornehmlich durch das Mitwirken einer großen Community, weniger durch den Testabdeckungsgrad. Die Defizite bei der Testbarkeit und Wartbarkeit von Drupal lassen sich sicherlich auch durch die Strategie des Verzichts auf Kompatibilität bei Release-Upgrades im Verein mit den schnellen Technologie-Zyklen erklären. Wenn der Code zum nächsten Release vielleicht schon wieder neu geschrieben werden muss, lohnt sich die Investition in wartbaren, flexiblen Code kaum.
In die Zukunft
Drupal drängt zunehmend in den Unternehmensmarkt. Mit dessen steigender Komplexität und steigendem Ressourcen-Bedarf wird Drupal zunehmend uninteressanter für private Nutzer oder zum Beispiel Vereine. Der Unternehmensmarkt dagegen verlangt nach flexiblen, professionellen Lösungen. Schwergewichtige Java Software positioniert sich seit vielen Jahren erfolgreich in diesem Bereich. PHP nähert sich augenscheinlich weiter an die objektorientierte Java-Welt an. Viele PHP-Anwendungen springen bereits auf den Trend zur Objektorientierung auf. Drupal verhält sich noch zögerlich.
Bis Drupal 8 zur Verfügung steht, werden vermutlich noch ein oder zwei Jahre vergehen. Danach wird es - nach bisheriger Erfahrung - ein weiteres Jahr dauern, bis das neue Release hinreichend gereift ist und das alte ablöst. Wird die bisher eingeschlagene Richtung beibehalten, wird Drupal in circa drei, vier oder fünf Jahren immer noch zum guten Teil prozedural ablaufen. Wenn ich von einer vergleichbaren Release-Zyklus-Dauer wie bisher ausgehe, käme Drupal 9 erst in etwa sechs Jahren zum Tragen. Vorher ist mit einem kompletten Umstieg auf Objektorientierung nicht zu rechnen.
Nach meiner Einschätzung wird es sich im Unternehmenskontext kaum ein PHP-basierendes CMS oder Framework leisten können, in den kommenden paar Jahren auf Objektorientierung zu verzichten. Ein Ausnahme mögen einfache Web Sites sein, bei denen es vordringlich darum geht, die "Außenfassade" aktuell zu halten. In Puncto PHP hat Drupal den Anschluss verloren. Wenn Drupal nicht schnell umsteuert - also beim kommenden Drupal 8 weit mehr auf OOP setzt als bislang geplant - gefährdet Drupal seine Marktstellung. Das betrifft zuerst nicht-amerikanische Länder wie Deutschland, in denen Drupal einen eher geringen Marktanteil aufweist. Ich denke nicht, dass es schon zu spät für ein Umlenken ist. Interessant erscheinen mir Ansätze zu sein, die auf ein bestehendes Web Framework aufsetzen. Erste Versuche dazu gibt es im Zusammenhang mit Symfony2 (siehe hier und hier). Sollten sich diese Ansätze als realisierbar erweisen, sollten sie noch in Drupal 8 einfließen - ein verspätetes Einfließen in Drupal 9 könnte für Drupal bereits zu spät sein.
Seit Jahren ist das Taxonomie-Modul ein wichtiger Bestandteil des Drupal-Kerns. Leider ist das Modul nicht für alle Anwendungsbereiche gleichermaßen gut geeignet. Insbesondere wenn die Anzahl der benötigten Terme hoch ist, kommt das Taxonomy-Modul schnell an seine Grenzen. Ich musste das zum Beispiel leidvoll bei meinem Drupal-Zusatzmodul Similar German Names erfahren: Alleine das Einspielen der Familiennamen in die Datenbank einschließlich der Kategorisierung nach Ähnlichkeit hätte ein paar Tage gedauert.
Mein neues Category-Modul könnte für manche Szenarien eine Alternative bieten. In diesem Beitrag stelle ich ein paar Ergebnisse von Vergleichstests vor.
Das Datastructure Category-Zusatzmodul
Das neue Datastructure Category-Modul ist für einige Szenarien als Alternative zum Taxonomie-Modul des Drupal-Kerns gedacht. In bestimmten Szenarien und Arbeitsbereichen läßt es das Taxonomie-Modul bei der Performance um etliche Größenordnungen hinter sich. Allerdings ist das Category-Modul derzeit nicht über die Web-Bedienoberfläche zugänglich. Im Moment ist das Modul also nur für Entwickler verwendbar.
Einige vergleichende Performance-Tests
Um die Eignung der beiden Module Datastructure Category sowie Taxonomy besser abschätzen zu können, führte ich mit Hilfe einiger Skripts Vergleichstests durch und variierte dabei die zu bearbeitenden Datenmengen:
Einspielen von Termen
Einspielen von Termen nebst Aufbau einer Term-Hierarchie
Zu allen Termen deren Eltern finden
Zu allen Termen deren Vorfahren finden
Bei der Term-Hierarchie werden jedem Term - mit Ausnahme der ersten zehn Terme - zwei Eltern-Terme zugeordnet. Pro Zehnerpotenz der Term-Anzahl kommt eine Hierarchie-Stufe dazu. Die Punkte 3 und 4 beziehen sich jeweils auf eine Sammlung von 10.000 Termen.
Details und Ergebnisse der Vergleichstests
Einspielen von Termen
Beim Taxonomy-Modul griff ich zur Durchführung der Aufgabe auf den Befehl
taxonomy_term_save($term)
zurück. Beim Category-Modul verwendete ich die Methode
addTerm($term)
Ich ließ jeweils die gleichen Berechnungen für eine Anzahl von 1, 10, 100, 1.000, 10.000 sowie 100.000 Termen durchführen. Die Zeitdauer ist jeweils in Einheiten von Sekunden angegeben (das gilt auch für die nachfolgenden Tabellen).
Die Ergebnisse fallen deutlich aus:
Anzahl Terme
Dauer Category
Dauer Core Taxonomy
Differenz-Faktor
1
0,159
0,204
1,3
10
0,123
1,261
10
100
0,122
12,726
104
1.000
0,156
120,337
771
10.000
0,267
1212,150
4.540
100.000
1,557
12165,737
7.814
Bei der grafischen Darstellung derselben Daten in Form eines Balkendiagramms greife ich auf eine doppelt-logarithmische Achsen-Skalierung zurück - für eine lineare Darstellung sind die Unterschiede zu groß:
Beim Aufbau von Termen skaliert das Taxonomy-Modul proportional mit der Anzahl der Terme. Die Aufgabe nimmt bei einer größeren Anzahl von Termen schnell sehr viel Zeit in Anspruch. Bei 100.000 Termen sind es bereits fast dreieinhalb Stunden.
Beim Category-Modul nimmt die Zeitdauer im getesteten Bereich nur unterproportional zu. Das Einfügen von 100 Termen geschieht noch ebenso schnell wie das Einfügen eines einzigen Terms. Erst bei 1.000 Termen erhöht sich die Dauer geringfügig. Auch bei größeren Term-Anzahlen nimmt die Laufzeit nur moderat zu.
Im Ergebnis ist das Category-Modul bei diesem Test dem Taxonomy-Modul weit überlegen; es arbeitet je nach Arbeitsbereich um Größenordnungen schneller. Bei 100.000 Termen etwa ist das Taxonomy-Modul fast 8.000 Mal langsamer als das Category-Modul. Und bereits beim Einfügen von 10 Termen ist das Category-Modul 10 Mal so schnell wie Taxonomy.
Noch höhere Anzahlen von Termen sind hier nicht dargestellt. Weitere Tests zeigten mir, dass auch bei einer weiteren Steigerung der Term-Zahlen die Bearbeitungszeit beim Category-Modul nur unterproportional wächst. Allerdings ist derzeit bei gut 400.000 Termen Schluss; darüber treten Überlaufsfehler auf (die Ursachen müsste ich erst genauer untersuchen ...).
Einspielen von Termen nebst Aufbau einer Term-Hierarchie
Bei der zweiten Testreihe werden ebenso wie in der vorhergehenden Testreihe Terme angelegt. Zusätzlich werden die Terme zueinander in eine Eltern-Kind-Beziehung gesetzt.
Beim Taxonomie-Modul verwende ich denselben Befehl wie vorher:
taxonomy_term_save($term)
Beim Category-Modul verwende ich zusätzlich zur bisherigen Methode eine weitere:
addTerm($term)
setParent($term, $parentTerm)
Für die zweite Testreihe habe ich mich auf weniger Fälle beschränkt; insbesondere bei einer kleinen Anzahl von Termen ist der Aufbau von hierarchischen Beziehungen zwischen den Termen weniger aussagekräftig. Hier die Ergebnisse:
Anzahl Terme
Dauer Category
Dauer Core Taxonomy
Differenz-Faktor
1.000
0,243
121,100
498
10.000
1,533
1207.44
788
100.000
15,918
...
...
Taxonomy benötigt zur Bewältigung dieser Aufgabe nicht mehr Zeit als bei der vorhergehenden Aufgabe. Das liegt einfach daran, dass Taxonomy das Anlegen der hierarchischen Beziehung mit demselben Befehl abhandelt, der auch für das Anlegen von Termen ohne Hierarchie-Beziehung verwendet wird.
Das Category-Modul ist bei dieser Aufgabe immer noch um Größenordnungen besser als das Taxonomy-Modul. Allerdings fällt der Unterschied nicht mehr so drastisch aus. Der zusätzliche Aufwand beim Aufbauen hierarchischer Beziehungen ist bei 1.000 Termen noch gering, bei 10.000 oder 100.000 Termen schlägt er jedoch deutlich zu Buche.
Zu allen Termen deren Eltern sowie deren Vorfahren finden
Zur Bewältigung dieser Aufgabenstellung greift das Taxonomy-Modul auf folgende beide Befehle zurück:
Das Category-Modul verwendet dagegen jeweils nur eine Methode:
getParents($term_name)
beziehungsweise
getAncestors($term_name)
Das Suchen von Eltern- und Vorfahren-Termen bei einer Gesamtheit von 10.000 Termen liefert keine derart eklatanten Unterschiede wie bei den ersten beiden Testreihen.
Die Ergebnisse:
Finden
Dauer Category
Dauer Core Taxonomy
Differenz-Faktor
Eltern
249,95
919,58
3,7
Vorfahren
1401,47
926,60
0,7
Beim Suchen der Eltern-Terme ist das Category-Modul immer noch fast viermal so schnell wie das Taxonomy-Modul. Bei der Vorfahren-Suche allerdings ist das Taxonomy-Modul sogar besser als das Category-Modul. Dieses Ergebnis könnte bei Verwendung eines etwas ausgefeilteren Such-Algorithmus ohne großen Aufwand für das Category-Modul deutlich verbessert werden - hier ist also Optimierungspotential beim Category-Modul vorhanden.
Der Grund für das günstigere Verhalten des Taxonomy-Moduls bei dieser Testreihe liegt offenbar im internen Caching begründet; beim Zugriff auf bereits vorher verwendete Terme wird der erneute Zugriff auf die Datenbank vermieden. Entwurfsbedingt kann das Category-Modul diese Art des Cachings nicht nutzen.
Unterschiedliche Entwurfsansätze der Category- und Taxonomie-Module und Konsequenzen
Der Entwurf beider Module unterscheidet sich grundlegend. Während das Taxonomie-Modul jeden einzelnen Term als Objekt ansieht und Terme sowie Term-Hierarchien in Datenbank-Tabellen feingranular abgegriffen werden können, ist beim Category-Modul eine gesamte Kategorie mit allen Termen und Beziehungen ein einziges Objekt (genauer gesagt besteht es aus einigen wenigen Objekten). Ein Category-Objekt wird mit einer einzigen Abfrage komplett aus der Datenbank gelesen und später mit einem einzigen Schreibvorgang wieder in die Datenbank geschrieben. Alle Operationen im Zusammenhang mit den Termen geschehen im Hauptspeicher. Die unterschiedlichen Entwurfsansätze beider Module haben teils gravierende Konsequenzen.
Feingranulares Datenbank-Caching ist beim Category-Modul nicht möglich. Ohne weitere Modifikationen ist die Skalierbarkeit des Category-Moduls im Prinzip begrenzter als beim Taxonomy-Modul. Allerdings deckt der Arbeitsbereich des Category-Moduls die Größenordnungen ab, die bei den meisten praktischen Anwendungsfällen relevant sein dürften, und ist hier dem Taxonomy-Modul teils eklatant überlegen. Soll von mehreren Seiten schreibend auf ein Category-Objekt zugegriffen werden, sind eventuell Maßnahmen zur Synchronisation erforderlich.
Wenn Taxonomie-Terme im Verlaufe des produktiven Betriebes sukzessive ergänzt werden, sollte das Taxonomy-Modul damit gut zu Rande kommen - von einigen Beschränkungen der Web-Oberfläche auf kleine Anzahlen von Termen abgesehen. Wenn aber insbesondere auf einen Schlag viele vorhandene Terme eingespielt oder migriert werden sollen, gelangt das Taxonomy-Modul schnell an seine Grenzen.
Abschließend sollte ich fairerweise noch darauf hinweisen, dass bei den obigen Aufrufen von Taxonomy-Befehlen intern noch weitere Aufgaben erledigt werden. Vor allem Hooks werden aufgerufen, um anderen Modulen die Gelegenheit zum Einklinken zu geben. Die Category-Befehle dagegen konzentrieren sich auf ihre ureigenen Aufgaben. Natürlich ist immer zu bedenken, dass es zum Taxonomy-Modul viele ergänzende Module gibt, während das Category-Modul neu ist.
Mein Datastructure-Modul macht gute Fortschritte. Trotzdem plane ich noch viele Erweiterungen. Ein Wechsel von einem Release 7.x-0.x nach 7.x-1.x kommt deshalb für mich in nächster Zeit nicht in Frage. Zudem veranlassen mich die Erfahrungen mit Drupal Entities, das weitere Vorgehen zu überdenken und geänderte Ziele anzustreben.
Status
Mit dem Release von aktuell 0.50-alpha1 nimmt der Quelltext der Modulsammlung bald ein Megabyte ein. Knapp 40% davon sind SimpleTests (über 2.300 Zusicherungen). Ebenfalls einen nicht unerheblichen Anteil am Quelltext nehmen die README-Datei sowie die Beschreibungen der öffentlichen Schnittstellen ein.
Neue Submodule
Neu hinzugekommen ist - neben den binären symmetrischen und asymmetrischen Relationen - das Category-Modul. Es ist als eine Art Alternative zum Taxonomy-Modul in Drupal Core gedacht, das sehr schlecht skaliert.
Das Category-Modul baut intern auf dem Datastructure-Modulen Map sowie den symmetrischen und asymmetrischen binären Relationen auf. Letztere beide Module dienen zur Realisierung von Synonymen und hierarchischen Eltern-Kind-Beziehungen. Das Map-Modul erledigt die Zuordnung der Terme zu den "Dingen" (also insbesondere zu Nodes).
Drupal Entities
Bei der Datastructure-Modulsammlung setzte ich von Anfang an auf Drupal Entities. Nach und nach wurde mir jedoch immer deutlicher bewusst, dass diese Entscheidung falsch war.
Entities orientieren sich aus meiner Sicht noch sehr eng an Oberflächen-nahen Objekten wie insbesondere Nodes. Datastructures sind dagegen als relativ generische Bausteine für Applikationen angelegt. Der erhoffte Nutzen durch die Anbindung von Entities blieb aus: Die Persistenz-Funktionen musste ich letztlich doch völlig selbst implementieren. Das durch Entites (einschließlich Entity API) vorgegebene Korsett empfinde ich als zu eng und an einigen Stellen unpassend für Datastructures. Die automatische Anbindung via Entities an das Rules-Modul bringt nicht allzu viel, denn es werden nur Basissituationen abgedeckt, die Datastructures kaum nützen. Auch hier müsste ich die relevante Anbindung selbst entwickeln.
Demgegenüber stehen bei der Einbindung der Entities einige Nachteile. Neben der zusätzlichen Komplexität wiegt vor allem die direkte Abhängigkeit zu Entities API schwer. Wenn sich diese Schnittstelle ändert, müssen unter Umständen die Datastructure-Module schnell nachgezogen werden.
Weiteres Vorgehen
Erweiterungen des Datastructure-Moduls sind noch in viele Richtungen möglich. Neben zusätzlicher Funktionalität bestehender Datastructures, weiterer elementarer Datastructures (vor allem Baumstrukturen) denke ich insbesondere an zusammengesetzte und verteilte Datastructures.
Ein ganz wesentlicher Schritt scheint mir jedoch die Loslösung von den Drupal Entities zu sein. Da ich von vorne weg auf ein Mindestmaß an Strukturierung geachtet habe, sollte es nicht schwer fallen, Datastructures ganz von Drupal abzukoppeln; wenn ich Datastructures als PHP-Bibliothek anbiete, könnte diese sowohl in Drupal als gegebenenfalls auch in andere Frameworks eingebunden werden.
In früheren Beiträgen wies ich bereits auf mein Drupal-Modul eines Zustandsautomaten hin. Hier zeige ich anhand eines Beispiels, wie mit dem API-Modul ein Zustandsautomat konfiguriert wird, und wie er zu bedienen ist. An den Anfang stelle ich ein Zustandsdiagramm, danach gebe ich die Abfolge der erforderlichen API-Aufrufe an.
Grafische Darstellung des Beispiel-Zustandsautomaten
Das Diagramm wurde mittels ArgoUML erstellt. Leider ist es bereits mit diesen wenigen Zuständen und Transitionen etwas unübersichtlich...
Erstellung des Zustandsautomaten
Der Zustandsautomat bekommt bei der Erzeugung einen Namen. Hinter der Variablen $fsm verbirgt sich der Zustandsautomat. Der Parameter commandLogging wird hier nur gesetzt, um später auf Wunsch die Abfolge der Zustandsübergänge nachvollziehen zu können.
$arguments = array(
'name' => 'Example State Machine',
'commandLogging' => TRUE
);
$factory = new DataStructureFactory();
$fsm = $factory->createInstance('DataStructureFsm', $arguments);
Konfiguration des Zustandsautomaten
Bevor der Zustandsautomat eingesetzt wird, sind die erlaubten Zustände, der Startzustand, die erlaubten Eingaben, die erlaubten Zustandsübergänge sowie optional anhand von Callback-Funktionen die verschiedenen Aktionen (Eingang, Ausgang, Eingaben, Zustandsübergänge) festzulegen:
Die zu den Aktionen angegebenen Callback-Funktionen sind noch geeignet zu definieren:
function _my_module_opened_exit_action() {...}
function _my_module_intermediate_exit_action() {...}
function _my_module_opened_entry_action() {...}
function _my_module_intermediate_entry_action() {...}
function _my_module_jump_input_action() {...}
function _my_module_opened_level1_transition_action() {...}
function _my_module_level3_intermediate_transition_action() {...}
Der Zustandsautomat in Aktion
Der Zustandsautomat ist nun startklar und reagiert ab sofort auf Eingaben (Inputs). Zu den Transitionen sind in Klammern häufig die Folgezustände angegeben. Hier nicht weiter angegeben sind etwaige Aktionen, die implizit entsprechend der Vorgaben aufgerufen werden.
$fsm->processInput('go to level1'); // 'level1'
$fsm->processInput('go to level2'); // 'level2'
$fsm->processInput('jump'); // 'intermediate'
$fsm->processInput('go to level1'); // 'level1'
$fsm->processInput('jump'); // 'intermediate'
Mit dem letzten Befehl wird der erreichte Zustand in die Datenbank abgespeichert; er könnte jederzeit wieder aufgegriffen werden.
Bedienoberfläche
Bei Aktivierung des mitgelieferten Bedienoberflächen-Moduls sind verschiedene Visualisierungen des erstellen Zustandsautomaten möglich. Neben der Anzeige von Daten und Attributen des Automaten sind Blöcke aktivierbar, die weitere Zustandsübergänge veranlassen können. Wird der Zustandsautomat als Field an einen Node Type angefügt, sind Workflows zu Node Types zu gestalten. Ein RSS-Feed mit den durchgeführten Zustandsübergängen rundet die Oberflächen-Funktionalität ab.
Drupal-Objekte wie etwa Nodes oder Users beinhalten traditionell nicht nur ihren Anwendungskern, sondern auch die Datenzugriffe sowie die Interaktion mit der Benutzeroberfläche. Diese Eigenheit ist für mich in Hinblick auf die Herkunft als oberflächenlastiges Content Management System plausibel. Je mehr sich jedoch Drupal in Richtung eines Anwendungs-Frameworks entwickelt, das zunehmend auf größere Unternehmensanwendungen abzielt, führt dieser Ballast zur Inflexibilität. Vor diesem Hintergrund ist die Erstellung meiner Modulsammlung Datastructure zu sehen. Nachfolgend möchte ich die wesentlichen Unterschiede grafisch verdeutlichen.
Drupal PODOs
In Anlehnung an das Akronym POJO - Plain Old Java Object - aus dem Java-Umfeld verwende ich hier zur Unterscheidung mit den Datastructures das Akronym PODO. PODO steht als Akronym für Plain Old Drupal Object. Mit PODOs meine ich die Eingangs erwähnten Drupal-Objekte.
Bei einer Drei-Schichten-Architektur könnten PODOs etwa wie folgt dargestellt werden:
Ein Node kümmert sich also selbst um die Anzeige der Inhalte an der Web-Oberfläche. Ebenso greift ein Node auf die Datenbank zu.
Datastructures
Anders verhält es sich mit Datastructures:
Datastructures sind nur in der Anwendungsschicht aktiv. Zur Persistierung in der Datenbank greifen sie auf eine Controller-Klasse zurück. Datastructures sind für sich genommen vollkommen unabhängig von der Bedienoberfläche.
Durch die Auftrennung der unterschiedlichen Perspektiven ergibt sich beim Einsatz eine höhere Flexibilität. Zum Beispiel könnten Drupal-Module sich alleine darum kümmern, Datastructures auf unterschiedliche Weisen an der Bedienoberfläche darzustellen. Matrizen könnten etwa zur Anzeige direkt in XHTML überführt werden; andere Perspektiven auf denselben Datenbestand könnten jQuery-Bibliotheken bieten. Drupal-Module könnten zur Bewältigung ihrer Anwendungen auf ein oder mehrere Datastructures zurückgreifen. Die Funktionalität der Datastructures kann ohne Neuentwicklung oder Cut-and-paste sofort verwendet werden; auf diese Weise müssen gleichartige Funktionalitäten nicht immer wieder neu erstellt werden. Die folgende Abbildung verdeutlicht das Prinzip: