Artikel

 
November 2009 | Artikel

Metawidget: King of the Hill Fortsetzung, Teil 2

Teil 1   Teil 2   Teil 3   Teil 4   

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.

  1. package de.javamagazin.mwd.nof;
  2. import java.util.Date;
  3. import org.nakedobjects.applib.annotation.*;
  4. public class Project
  5. {
  6. private String name = null;
  7. private String description = null;
  8. @MemberOrder(sequence="1")
  9. @Named("Projektname")
  10. @MaxLength(value=50)
  11. @RegEx(validation = "[A-Za-z]\\w+")
  12. public String getName() {
  13. return this.name;
  14. }
  15. @MemberOrder(sequence="2")
  16. @Named("Beschreibung")
  17. @Optional
  18. @MultiLine(numberOfLines=10)
  19. public String getDescription() {
  20. return this.description;
  21. }
  22. public void saved() {
  23. // Logik
  24. }
  25. @Named("Projekt abschliessen")
  26. public void finishProject(@Named("Enddatum") Date endDate) {
  27. // Logik
  28. }
  29. }

Teil 1   Teil 2   Teil 3   Teil 4   

Anzeige

Kommentare

Gravatar RPR 25.11.2009
um 20:24 Uhr
Für einfache Prototypen ist so was ja ganz nett; aber:1. Für ausgefeilte Endkunden-GUIs die komplexe Business-Logik darstellen sollen ist so was nicht geeignet.2. Schon die GUI des einfachen Beispiels sieht - pardon - besch... aus; die Labels gehören z.B. rechtsbündig.3. Der Code des Beispiels wäre mit Swing allein auch nicht länger gewesen; höchstens die Validierung (die auch nur in einfachsten Fällen so geht - wie siehs z.B. mit dynamischen Lookups aus?) bringt ein paar Zeilen Code; verstopft aber die Übersichtlichkeit; pro Property 10 Annotations? Nein danke.4. Durch die ganzen Interzeptoren XML-Einlesearbeit etc. wird das Programm sicher nicht schneller (starten).Woher kommen wohl seit 10 Jahren die "Gerüchte" dass Java-GUIs hässlich und langsam sind? Nicht zuletzt von solchen "Vereinfachungen".Nein Leute lasst euch sagen: Wenn ein Programm erfolgreich werden soll dann braucht es eine ausgefeilte Benutzerführung dass die Leute sagen: Geil das macht das genau so wie ich mir das vorstelle. Ansonsten werden die Benutzer das Programm von Anfang an hassen. Ergo: Für die nächste Franken-GUI durchaus eine Überlegung wert ;-) #zitieren
Gravatar RPR 25.11.2009
um 20:26 Uhr
Jetzt geht der vermaledeite Zeilenumbruch hier schon wieder nicht welche Stümper programmieren das hier eigentlich? #zitieren
Gravatar Wolfgang Gruber 26.11.2009
um 15:37 Uhr
ad 1. nein, dazu ist es auch gar nicht gedacht. Es soll die Entwicklung von Standard-Formularen vereinfachen, die meist einen großen Teil von Applikationen einnehmen. Komplexe GUIs erfordern natürlich weiterhin "Handarbeit".
ad 2. Stimmt, es ist aber nur ein kurzes Beispiel. Auf http://metawidget.sourceforge.net/screenshots.html gibt es einige schönere GUIs.
ad 3. Bei kurzen Beispielen machen sich die Einsparungen an Source Code natürlich nicht bemerkbar. Zum Vergleich: Wenn man den Code für ein einfaches JDBC-Select-Statement mit dem Code vergleicht, den JPA für die gleiche Funktionalität benötigt, dann schneidet JPA auch nicht gerade gut ab. Es geht aber auch darum repetativen Code zu eliminieren, so dass man sich als Entwickler mehr auf den Kern konzentrieren kann. Im Fall von Metawidget eben die Anordnung der Widgets, sowie deren Aussehen. Ob man alle Metadaten als Annotationen direkt in der Entität angibt oder in XML-Dateien auslagert (wie das auch von Metawidget angeboten wird), bleibt jedem Entwickler selbst überlassen. Momentan ist es eben einfach der Trend alles in Annotationen zu packen. Ob das der ideale Weg ist, ist natürlich eine andere Frage :-)
ad 4. das Problem ist, dass solche Gerüchte einmal aufkommen und dann nicht mehr hinterfragt werden. Inzwischen sind 10 Jahre vergangen, in denen sich sowohl Java, als auch die darunterliegende Hardware weiterentwickelt haben. Ansonsten kommen langsame Java-GUIs sehr oft von suboptimaler Programmierung, z.B. dass zu viel Arbeit im Event Dispatch Thread erfolgt, die GUI dadurch "einfriert" und nicht mehr auf den Benutzer reagiert.
Metawidget bildet einen Wrapper um vorhandene Technologien und ist mit knapp 300 KB nicht besonders groß. Von daher ist die Performance-Einbuße beim Start zwar sicherlich vorhanden, aber nicht wesentlich (die Initialisierung von z.B. JPA nimmt da sicherlich mehr Zeit in Anspruch).
Wie im Artikel beschrieben, handelt es sich nicht um eine All-inclusive-Lösung, sondern einfach um ein Tool, dass die Arbeit mit Formularen erleichtern soll.
#zitieren
Gravatar Jan Lessner 26.11.2009
um 22:48 Uhr
Ich kann nur bestätigen, dass solche Ansätze funktionieren. Wie ich seinerzeit in dem zitierten Artikel über Naked Objects geschrieben hatte, ließt an dem Framework nicht das Konzept sondern nur die konkrete Umsetzung zu wünschen übrig. Inzwischen haben wir bei arvato services ein eigenes Framework nach Naked-Objects-Pattern entwickelt, das tadellos im produktiven Einsatz funktoniert, enorm Zeit spart und trotzdem flexibel und offen ist, so dass selbst die kritischen Entwickler das Ding richtig "cool" finden. Entscheidender Trick dabei: die zur Laufzeit erzeugten Maskenlayouts (basierend auf JGoodies FormLayout) werden - sofern man es nicht explizit unterdrückt - in Dateien abgelegt und lassen sich anschließend mit einem sehr komfortablen GUI-Designtool nachbearbeiten. Dadurch sind auch hohe Ansprüche an die äußerliche Gestaltung erfüllbar und es können eine ganze Reihe von Annotatinen im Sourcecode vermieden werden, die reine Oberflächenthemen betreffen, z.B. Default-Buttons, Tab-Reihenfolge, Ausblenden von Feldern usw. Bei nachträglichen Ergänzungen der Domänenklassen werden Felder für neue Attribute in die bestehenden Layouts vom Framework zur Laufzeit hinein gemerged.
Mit dieser Technik erschlagen wir 80% aller GUIs. Wichtig ist natürlich die Offenheit der Umgebung für die restlichen 20%, wo tiefe Eingriffe notwendig sind. Mit ein bisschen Kenne lässt sich auf Basis der vielen verfügbaren Toolkits in der Java-Welt ein sehr schlankes Naked-Objects-Framework bauen. Wir setzen z.B. auf AjaxSwing, um unsere generisch erzeugten Swing-Oberflächen ins Web zu kriegen.
#zitieren
Gravatar RPR 28.11.2009
um 12:09 Uhr
Hallo Jan,
nun gut, wenn man die GUIs nachbearbeiten kann, ohne den Bezug zum Original zu verlieren (was ein wirklich beeindruckendes Feature ist - die meisten UML-Tools können das nicht mal) und nachträglch reinmergen kann und das gut funktioniert, ist es sicher ne Möglichkeit, sich hier Zeit zu sparen und konsistent zu bleiben. Das Ding ist nicht zufälligerweise open source oder kann man mal wo testen?

Ein Schmunzeln entlockte mir der Satz "Mit dieser Technik erschlagen wir 80% aller GUIs" - so wie viele Java-GUIs aussehen, muss man wirklich von "Erschlagen" sprechen ;-)
#zitieren
Gravatar Jan Lessner 30.11.2009
um 11:40 Uhr
Das stimmt schon - viele GUIs werden von Entwicklern gestaltet, und die haben in der Regel nicht Gestaltung studiert, und das sieht man dann auch ;-)
Ich find's aber OK, das Hauptaugenmerk auf die wirklich wichtigen Dinge zu lenken und an "Nebenkriegsschauplätzen" nicht von vornherein Aufwand für Usability zu spendieren. insbesondere ist es gut, wenn sich da im Nachgang ohne Codeänderung einiges drehen lässt, und das ist genau unsere Intention gewesen. Wir setzen übrigens als GUI-Designtool den JFormDesigner ein, der so komfortabel ist (und insbesondere losgelöst von einer fetten IDE), dass die Fachbereiche es sich nach einer Weile auch selber zutrauen, die Controls an die richtigen Stellen zu schubsen.

Das Toolkit ist leider noch nicht Open Source obwohl es das werden soll. Ich muss unseren Abteilungsleiter noch ein bisschen bearbeiten - das ist mir mit einem anderen Framework in der Vergangenheit auch schon gelungen, deswegen sollte das diesmal auch klappen ;-)
Im Moment schleifen wir noch ein paar Ecken rund. Wenn es Dich sehr interessiert, kann ich checken, ob Du's gegen ein NDA mal haben kannst.
#zitieren

Anzeige

zurück zum Seitenanfang
X