Alternative Ansätze
Moment mal, wird sich an dieser Stelle manch einer denken: Da gibt es doch andere Technologien, die genau diesen Problembereich abdecken. Stimmt schon, natürlich gab es auch im Bereich der User-Interface-Technologien in den letzten Jahren einige neue Ansätze. Im Folgenden geht es um zwei andere Technologien, die ebenfalls angetreten sind, um die Arbeit mit User Interfaces zu erleichtern. Mit Ruby on Rails (RoR) ist im Jahr 2004 ein neuer Stern am Himmel der Webframeworks aufgegangen. War die Entwicklung von Webapplikationen in der Java-Welt bis zu diesem Zeitpunkt recht kompliziert und schwerfällig, zeigte RoR neue Wege auf, indem es Prinzipien wie Don't repeat yourself (DRY) und Convention over Configurations folgte. Seinen Erfolg verdankt RoR auch dem Scaffolding, immerhin ermöglicht erst dieses Feature, innerhalb weniger Minuten vollständige Datenbankapplikationen zu erstellen. Bei Scaffolding wird die komplette CRUD-Funktionalität für ein Domänenobjekt mit allen User-Interface-Masken und den erforderlichen Controller-Klassen generiert.
Um in der Java-Welt zu bleiben, wollen wir uns ansehen, wie dieses Feature von Grails (siehe auch Sven Haiges: Grails – Die Serie, in Java Magazin 4.2007–8.2007) umgesetzt wird. Bei Grails handelt es sich um ein in Groovy entwickeltes Webframework, das viele Ideen von RoR übernommen hat. Ausgehend von einer bestehenden Domänenklasse können wir wählen, ob wir dynamisches oder statisches Scaffolding bevorzugen. Bei dynamischen Scaffolding wird jedes Mal beim Starten der Applikation die CRUD-Funktionalität dynamisch zur Verfügung gestellt. Dies ist im Endeffekt der gleiche Ansatz wie bei Metawidget, mit dem Unterschied jedoch, dass man bei Grails deutlich weniger Einfluss auf das Ergebnis nehmen kann.
Beim statischen Scaffolding genügt der Befehl grails generate-all, um für eine Domänenklasse den gesamten Code für die CRUD-Funktionalität mit dem Controller, den darin enthaltenen Methoden und allen User-Interface-Masken (Views) generieren zu lassen. Nachdem sich dynamisches Scaffolding zwar für Rapid Prototyping eignet, jedoch für Produktivsysteme keine Option darstellt, wird de facto in allen Projekten vom generierten Code ausgegangen, um diesen zu modifizieren und an die eigenen Bedürfnisse anzupassen. Selbst dies ist bereits eine große Erleichterung für Entwickler, da es einfacher, schneller und weniger fehleranfällig ist, Template-basierten Code anzupassen als den Code komplett neu zu schreiben. Im Gegensatz zu dynamisch erzeugten Formularen wie sie Metawidget bietet, müssen jedoch bei jeder Änderung an der Domänenklasse auch die Views manuell angepasst werden. Außerdem ist Grails, so mächtig und einfach anwendbar es auch ist, auf eine einzige Domäne, nämlich Webapplikationen, beschränkt.
Naked Objects (auch Jan Leßner: Was geht mit Naked Objects?, in Java Magazin 4.2008 ) verfolgen einen komplett eigenständigen Ansatz, wobei der Name hierbei sowohl für das dahinterstehende Architektur-Pattern als auch für ein konkretes Framework steht. Entgegen aktuellen Architekturen, die eine Applikation in mehrere Schichten einteilt, die für bestimmte Aufgaben zuständig sind, basiert Naked Objects auf einer Idee, die sich wieder der reinen Lehre der Objektorientierung annährt, indem es die Domänenobjekte in den Mittelpunkt stellt. Diese kapseln sowohl die Daten als auch die eigentliche Logik der Applikation. Zusätzlich werden die Objekte um spezielle Metadaten in Form von Annotationen angereichert, die das Framework für die Erstellung der Eingabeformulare sowie die Verarbeitung der Daten benötigt. Naked Objects setzt von Haus aus einem engen Rahmen, wie die Entwicklung von Applikationen zu erfolgen hat, und gibt dem Entwickler nicht viel Handlungsspielraum, was die Architektur und das Design der Applikation betrifft. Dieser Aspekt mag jedoch von manchem als Vorteil, von anderen als Nachteil gesehen werden. Listing 1 zeigt ein Domänenobjekt, wie es bei Naked Objects zum Einsatz kommen könnte. Die Klasse besteht aus zwei Properties und zwei Methoden, wobei deren Rumpf aus Gründen der Übersichtlichkeit entfernt wurde. Jedes der beiden Properties soll auf der Eingabemaske erscheinen, wobei der Reflektion-Mechanismus von Java nicht garantiert, dass die Properties in der gleichen Reihenfolge ausgelesen werden wie sie in der Sourcecode-Datei angeführt sind. Daher gibt es die @MemberOrder-Annotation, die die genaue Reihenfolge festlegt. Im Beispiel vergeben wir des Witeren mittels der @Named-Annotation einen Namen für den Property, der dann im Formular als Label angezeigt wird. Natürlich wird aber auch die Internationalisierung unterstützt, in dem die Namen aus Ressourcendateien ausgelesen werden. Darüber hinaus gibt es eine Reihe weiterer vom Naked-Objects-Framework definierte Annotationen wie @MaxLength, @Optional, @RegEx oder @MultiLine, die das Verhalten der Applikation beeinflussen. Bei der Methode saved handelt es sich um eine spezielle Life-Cycle-Methode, die anhand ihres Namens erkannt wird und automatisch aufgerufen wird, wenn das Objekt das erste Mal gespeichert wird. Die Methode finishProject schließlich ist eine Action, d. h. eine Methode, die über das User Interface ausgeführt werden kann.
package de.javamagazin.mwd.nof;import java.util.Date;import org.nakedobjects.applib.annotation.*;public class Project{private String name = null;private String description = null;@MemberOrder(sequence="1")@Named("Projektname")@MaxLength(value=50)@RegEx(validation = "[A-Za-z]\\w+")public String getName() {return this.name;}@MemberOrder(sequence="2")@Named("Beschreibung")@Optional@MultiLine(numberOfLines=10)public String getDescription() {return this.description;}public void saved() {// Logik}@Named("Projekt abschliessen")public void finishProject(@Named("Enddatum") Date endDate) {// Logik}}














