13
Ereignisbasierte Web-GUIs Dennis Knotz 20. August 2010 Inhaltsverzeichnis 1 Motivation 2 2 Einf¨ uhrung 2 2.1 Request-Response Muster .......................... 2 2.2 Ereignisbasiertes Muster ........................... 3 3 Verwendung einer ereignisbasierte Architektur im WWW 4 3.1 Oberfl¨ ache ................................... 4 3.2 Sessions .................................... 6 3.3 Ereignisse ................................... 7 3.4 Container ................................... 8 3.5 Zusammenspiel der Komponenten ...................... 8 4 Beispiel: wingS 10 4.1 Architektur .................................. 10 4.2 Eventerzeugung ................................ 11 4.3 AJAX ..................................... 11 4.4 Beispiel .................................... 12 5 Fazit 12 6 Quellen 13 1

Ereignisbasierte Web-GUIs · Wenn ein Ereignis eintritt, meldet es der Noti er an alle Abonnenten des entsprechen-den Ereignisses. Dabei kann ein Noti er, im Unterschied zur Abbildung

  • Upload
    others

  • View
    2

  • Download
    0

Embed Size (px)

Citation preview

Ereignisbasierte Web-GUIs

Dennis Knotz

20. August 2010

Inhaltsverzeichnis

1 Motivation 2

2 Einfuhrung 22.1 Request-Response Muster . . . . . . . . . . . . . . . . . . . . . . . . . . 22.2 Ereignisbasiertes Muster . . . . . . . . . . . . . . . . . . . . . . . . . . . 3

3 Verwendung einer ereignisbasierte Architektur im WWW 43.1 Oberflache . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 43.2 Sessions . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 63.3 Ereignisse . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 73.4 Container . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 83.5 Zusammenspiel der Komponenten . . . . . . . . . . . . . . . . . . . . . . 8

4 Beispiel: wingS 104.1 Architektur . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 104.2 Eventerzeugung . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 114.3 AJAX . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 114.4 Beispiel . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 12

5 Fazit 12

6 Quellen 13

1

1 Motivation

Grafische Benutzerschnittstellen im WWW werden typischerweise durch das vomEntwurf des Internets vorgegebenen Request-Response Muster realisiert. Dieses Musterist historisch bedingt und bietet nicht die gewohnte Abstraktion moderner Ober-flachenbibliotheken. Das Design ist dabei stark an die Request-Response Strukturgebunden.

Ereignisbasierte Oberflachen bieten einen hoheren Abstraktionsgrad. Beim Designmuss keine Rucksicht auf die tieferliegende Struktur genommen werden. Dadurch lassensich Programme eleganter entwerfen.

Ein Toolkit, das diese Art der Weboberflachenprogrammierung ermoglicht, istwingS. Es ahnelt in seiner Programmierart stark an die Java-GUI-Bibliothek Swingund ermoglicht es somit den Entwicklern Weboberflachen im Stile von Desktop-GUIszu entwerfen.

2 Einfuhrung

2.1 Request-Response Muster

Das Request-Response Muster wird haufig bei Client-Server Architekturen, wieWebseiten, genutzt. Wahrend die Interaktion des Benutzers an der Oberflache desClients erfolgt, werden die benotigten Daten zuerst uber Nachrichten an den Serverubertragen. Dieser ist fur die Verarbeitung zustandig und ubergibt nach Beendi-gung das Ergebnis wieder an den Client, der es dann fur den Nutzer sichtbar darstellt.Ein schematischer Ablauf dieser Kommunikation ist in Abbildung 1 zu sehen.[2, S. 154ff]

Nachricht an Server

Aktion mit dem Programm

Antwort von Server

Darstellen der Änderung

Abbildung 1: Nachrichtenubertragung beim Request-Response Muster

In diesem Paradigma hangt die Programmierung stark vom moglichen Ablauf des Pro-grammes ab. Bei der Webentwicklung wird auf Nachrichten mit einer neuen Oberflachereagiert und die bisher existierende verworfen. Es muss auch darauf geachtet werden, dass

2

die Nachrichten, die der Client an den Server schickt auch verarbeitet werden konnenund die Antwort ein darstellbares Format besitzt.

2.2 Ereignisbasiertes Muster

Das Paradigma der ereignisbasierten Programmierung tritt oft bei der Entwicklung vonDesktopoberflachen auf. Bei der Interaktion wird automatisch ein sogenannter Eventerzeugt, der der Anwendung mitteilt, dass ein Ereignis aufgetreten ist. Dies konntebeispielsweise die Anderung eines Textfeldes sein. Das Programm reagiert dann aufdiesen Event.

Dabei kommt meist das Observer-Muster zum Einsatz. Objekte, die auf Ereignissereagieren sollen, konnen sich hierbei an einem Bekanntmachungsobjekt (Notifier)anmelden, das alle Events an die entsprechenden Uberwacher (Observer) weiterleitet.Dies geschieht uber ein Interface, dass alle Observer implementieren und durch das esdem Notifier moglich ist, die Ereignisse ohne genaue Kenntnis des Empfangerobjektszu verteilen. Die Implementierung dieses Interfaces ist dann dafur zustandig, dienotigen Anderungen nach dem Ereignisauftritt durchzufuhren. Das Design eines solchenObserver-Musters ist in Abbildung 2 dargestellt.[1, S. 301ff]

+notifyObservers()+addObserver(in ObserverInf)+removeObserver(in OberverInf)

Notifier

+update()

Observer

+update()

«interface»ObserverInterf

+changeState()

ObservedObject

Abbildung 2: Observer-Muster Klassendiagramm (frei nach [1, S. 302])

3

Wenn ein Ereignis eintritt, meldet es der Notifier an alle Abonnenten des entsprechen-den Ereignisses. Dabei kann ein Notifier, im Unterschied zur Abbildung 2, auch furverschiedene Ereignisse zustandig sein. In Abbildung 3 ist zu sehen, dass der Abonnentdes Events B nicht informiert wird, falls Event A auftritt. Das Bekanntmachungsobjektmuss nicht wissen, wie die interne Struktur des Abonnentenobjekts aussieht, da es nurdafur zustandig ist, die Ereignisse zu verteilen. Die Abonnenten reagieren dann auf deneingetroffenen Event selbst.

Notifier

Aktion des Nutzers (Event A)

Registrieren (Event A)

Registrieren (Event A)

Registrieren (Event B)

Über Event informieren

Über Event informieren

Abbildung 3: Bekanntmachung eines Events

Der Programmierer kummert sich im ereignisbasierten Muster nicht um die Dat-enubertragung zwischen Oberflache und Logik. Er programmiert darin im Hinblick aufdie auftretenden Events. Dadurch ist es moglich, den Verlauf des Programmes weitest-gehend zu vernachlassigen.

3 Verwendung einer ereignisbasierte Architektur imWWW

Um im Bereich der Weboberflachen das ereignisbasierte Muster verwenden zu konnen, istes notig, das Request-Response Muster darauf abzubilden. Um dies zu ermoglichen, mussman sich vom vorhandenen Client-Server Modell losen und die Webprogrammierung ineinigen Bereichen anpassen.

3.1 Oberflache

Die Oberflachenprogrammierung in HTML kann kein Reagieren auf Events darstellen.Um das Observer Muster verwenden zu konnen, benotigen die Oberflachenelemente dieMoglichkeit, bei den benotigten Events den Notifier zu informieren. Dieser kann sie dannan die Observer der abstrahierten Oberflachenelemente weitergeben. Die Umwandlungin die HTML Darstellung wird aus Grunden der Objektorientierung innerhalb einer

4

Buildmethode realisiert. Weiter benotigt die Klasse nur die notigsten Funktionen (Textsetzen und auslesen, bei Konstruktion eindeutige ID generieren), das Verwalten derbenotigten Observer (oder Listener) und die Bekanntmachung des Events. Ein moglicherEntwurf der Oberflachenobjekte ist in Abbildung 4 zu sehen. Durch das Erben der”notify(int i)”Funktion konnen alle GUI Elemente auf die selbe Art und Weise Eventserzeugen. Da viele Oberflachenelemente auf mehrere unterschiedliche Events reagierenmussen, wird durch den Parameter i die ID der Eventart ubergeben. Durch dieses Designder Oberflachenelemente ist es moglich, nachtraglich GUIObjekte einzufugen, ohne dieweiteren Implementierungsklassen andern zu mussen.

+notify(in id : int)+build(in PrintWriter)

GUIObject

+addChangeListener(in ChangeListener)+removeChangeListener(in ChangeListener)+notify(in id)

-ChangeListeners

TextField

+addActinoListener(in ActionListener)+removeActionListener(in ActionListener)+notify(in id)

-ActionListeners

AbstractButton

+...()

-...

...

Button ToggleButton

Abbildung 4: Klassenaufbau der Oberflachenelemente

Ein gutes Beispiel fur eine ereignisbasierte Oberflachenprogrammierung bietet dieJava GUI-Bibliothek Swing. Dort konnen fur jedes GUI-Objekt verschiedene Listenerimplementiert werden, die dafur zustandig sind, auf die auftretenden Ereignisse zureagieren.

Um die Oberflachenelemente am Client wieder korrekt darstellen zu konnen, muss einUbersetzer (Builder) eingesetzt werden. Er delegiert die Umwandlung der aktuellenSession in gultigen HTML Code. Dabei ruft er fur jedes GUIObjekt im Sessionbaumdessen Buildmethode auf. Diese Methode ist neben der simplen Darstellung auch dafurzustandig, das bei einem auftretenden Event eine gultige Nachricht an den Servergeschickt wird. Dafur wird das aktuelle Servlet neu geladen, und die eindeutige ID desObjekts und die Event-ID ubertragen.

5

Ein stark gekurztes Beispiel unter Verwendung von JAVA Servlets zeigt, wie der Builderaus einem Button-Objekt HTML Code erzeugen kann. Dabei ruft der Builder fur jedesSessionobjekt dessen Methode build(PrintWriter out) auf. Der PrintWriter schreibtdann direkt in die Ausgabe.

1 public class Bui lder {2 public stat ic void bui ldUI ( Pr intWriter out , Se s s i on output )3 {4 out . p r i n t l n ( ”<html>” ) ;5 out . p r i n t l n ( ”<body>” ) ;6 for ( int i =0; i<output . s i z e ();++ i ){7

8 GUIObject obj = output . get ( i ) ;9 obj . bu i ld ( out ) ;

10 }11 out . p r i n t l n ( ”</body>” ) ;12 out . p r i n t l n ( ”</html>” ) ;13 }14 }15 public class Button extends AbstractButton{16 . . .17 public void bu i ld ( Pr intWriter out )18 {19 out . p r i n t l n ( ”<input type=’button ’ id=’”+this . id+ ” ’ va lue=’”20 + ””+this . t ex t+” ’ ” ) ;21 i f ( this . g e tAc t i onL i s t ene r s () != null &&22 this . g e tAc t i onL i s t ene r s ( ) . length >0)23 out . p r i n t l n ( ”OnClick=’window . l o c a t i o n =\”.?”+id+”=1\” ’” ) ;24 out . p r i n t l n ( ”/>” ) ;25 }26 }

3.2 Sessions

Ein weiterer großer Unterschied zwischen den zwei zu verbindenden Paradigmenbesteht in der Zustandsbehaftung: Da es bei einer Oberflachenprogrammierung imRequest-Response Muster meist genau vorhersehbare Vorgangerzustande gibt, ist eineSessionverwaltung nicht notig. Die ereignisorientierte Programmierung basiert darauf,den aktuellen Zustand des Programmes zu kennen. Dabei wird nach außen nichtunterschieden, an welcher Stelle des Programmes man gerade ist, sondern nur deraktuelle Zustand dargestellt. Die komplette Zustandsverwaltung ist vom Anwenderunsichtbar im Backend versteckt.

Es soll nicht moglich sein, dass nicht aktive Oberflachenelemente Ereignisse erzeugenbzw. darauf reagieren. Eine Moglichkeit dies zu verhindern ist es, einen Strukturbaumder aktuell verwendeten Objekte aufzubauen und diesen dann zu speichern. Dabei ist eshilfreich, die Session so zu implementieren, dass sie jedes Objekt durch seine eindeutigeID identifizieren kann. Bei jeder Anderung wird ein neuer Baum erzeugt und als neuerZustand gesichert. Objekte, die in diesem Strukturbaum nicht vorhanden sind, konnen

6

nicht auf Eventnachrichten reagieren.

Um sich den Zustand merken zu konnen, bietet es sich an, eine geeignete Webtechnolo-gie zu verwenden. Eine solche Technologie bieten beispielsweise die Java Servlets. Siebesitzen die Moglichkeit, uber ein

”HTTPSession“-Objekt beliebige Java-Inhalte uber

den kompletten Nutzzyklus des Servlets zu speichern, andern und diese auch wiederauszulesen.

3.3 Ereignisse

Um Ereignisse, auch Events genannt, erzeugen zu konnen, mussen die am Serverankommenden Nachrichten analysiert und in Ereignisse umgewandelt werden. Dabeiist es wichtig, dass sowohl jedes verwendete Oberflachenelement, als auch die Art desEvents, eindeutig identifiziert werden konnen. Es sollte ein Bekanntmachungsobjektverwendet werden, das dafur sorgt, dass die Elemente, die auf dieses Ereignis reagierensollen auch informiert werden.

Ein EventHandler liest die Nachrichten aus. Danach sucht er in der Session nachdem Objekt, das fur diesen Event verantwortlich ist und fuhrt dessen Bekannt-machungsmethode aus. Dabei ubergibt er die ID des Events, damit das Objekt,falls mehrere unterschiedliche Events existieren, nur die Observer fur den aktuellaufgetretenen Event informieren. Diese Observer ubernehmen dann die Aufgabe, dieAnderungen durchzufuhren. Eine mogliche Implementierung eines EventHandlers kannwie folgt aussehen:

1 public class EventHandler {2

3 public stat ic void handleEvent ( HttpServ letRequest req , Se s s i on s e s ) {4 try{5 Enumeration<Str ing> params = req . getParameterNames ( ) ;6 while ( params . hasMoreElements ( ) ) {7 // Name des Name Werte Paares = ID des Objek t s8 St r ing id = params . nextElement ( ) ;9

10 // Methode der Sess ion um ein Objekt zur ID zu f inden11 GUIObject o = se s . get ( In t eg e r . valueOf ( id ) ) ;12

13 // ID der Eventart aus l e s en14 int i = In t eg e r . valueOf ( req . getParameter ( id ) ) ;15 // Bekanntmachung des Events16 o . n o t i f y ( i ) ;17 }18 }catch ( Exception e ){}19 }20 }

Hierbei werden alle Events, die ubermittelt werden, nacheinander ausgewertet. Esist vorteilhaft, eine Priorisierung vorzunehmen, falls mehrere Events innerhalb einer

7

Nachricht ubertragen werden. Diese Priorisierung kann jedoch mit Hilfe eines gutenUbersetzers schon in der Nachricht realisiert werden. Geschieht eine solche Priorisierungnicht, ist die Moglichkeit eines nicht-deterministischen Verhaltens des entworfenen Pro-grammes gegeben, was zu ungewollten Seiteneffekten fuhren kann. Ein Beispiel furmehrere Ereignisse konnte zum Beispiel das Ubertragen eines Formulars sein. Dabeisollte logischerweise die Anderung der Textfelder vor dem Event des Absende-Buttonsausgefuhrt werden.

3.4 Container

Um diese Elemente nun miteinander verbinden zu konnen, ist es notig, sie in einemContainer zu verwalten. Der Container ist dafur zustandig, dass das Zusammenspielder Komponenten reibungslos funktioniert. Das Ansprechen der Oberflache uber denBrowser erfolgt ebenfalls uber diesen Container. Im Servlet-Kontext konnte dies eineinfaches Servlet sein, das die einzige Aufgabe hat, die Subkomponenten zu deligierenund die Session zu verwalten.

3.5 Zusammenspiel der Komponenten

Ein mogliches Zusammenspiel der Komponenten kann wie in Abbildung 5 dargestelltaussehen:

8

MainServlet Logic EventHandler Builder

Erster Aufruf

Session vorhanden?

Erzeuge Programm

Fertig

Erstelle Oberfläche

Client

Sende GUI an Client

Aufruf mit Event als Nachricht

Speichere Session

Session vorhanden? Lade Session

Behandeln der Events

Events behandelt

Erstelle Oberfläche

Sende neue GUI an Client

Speichern der neuen Session

Abbildung 5: Ablaufdiagramm bei Aufrufen

Beim ersten Aufruf wird der Container (MainServlet) nach einem vorhandenen Zustandgefragt. Da dieser keine vorhandene Session findet, wird in der Logik der Initialzustanderstellt. Dieser Zustand wird als aktuelle Session gespeichert. Da noch kein Eventstattgefunden haben kann, wird der EventHandler nicht angesprochen, sondern direktdurch den Builder eine Ausgabe erzeugt und an den Client ubergeben.

Wird nun an der Oberflache ein Event ausgelost, wird dieser mit der Identifika-tion des Objekt und der Art des Events in einer Nachricht wieder an das MainServletgeschickt. Dieses erkennt jetzt, dass bereits eine Session vorhanden ist und startet nichtdie Logik um den Initialstatus aufzurufen. Stattdessen erhalt der EventHandler dieNachricht. Dieser reicht den Event an das entsprechende Sessionobjekt weiter, das uber

9

seinen Observer die Anderungen durchfuhrt. Dabei wird auch auf die Logik zugegriffen.Nachdem dies abgeschlossen ist, wird die neue Session wieder gespeichert und derBuilder erzeugt darauf aufbauend die neue Ausgabe.

4 Beispiel: wingS

Das Framework wingS (wings is net generation Swing) versucht, die oben genanntenPrinzipien umzusetzen und den Entwicklern so die Moglichkeit zu bieten, ihre Webober-flache wie Swing zu programmieren.

4.1 Architektur

wingS verwendet Java-Servlets, um das Ziel, ereignisbasierte Webprogrammierung zuermoglichen, umzusetzen. Die Klassen zum Erstellen der Oberflache unterscheiden sichim Funktionsumfang kaum von den verwandten Swing-Objekten. Beim Aufruf wird einSession-Servlet mit dazugehoriger Session erzeugt, um den aktuellen Zustand des Pro-grammes zu verfolgen, in der der komplette Komponentenbaum und Zustand des Pro-grammes gespeichert wird. Fur jeden Nutzer existiert genau eine Session, die an denaktuellen Zustand angepasst wird. Diese Session beinhaltet eine fortlaufende Nummer,um alte Nachrichten identifizieren und ignorieren zu konnen. Solche alten Events konnenbeispielsweise durch das Verwenden des

”Zuruck“-Buttons des Browsers auftreten.[4, S.

28ff]

10

Client

Java Servlet API

Event Dispatcher

SFrame

SButton SPanel

SLabel STextfield…

Externalizer

LEE LLE LLE

An

wen

du

ngs

logi

kAPI

Aufrufe

HLEs

HTTP Request HTTP Response

Ren

der

er

wingS Session

Abbildung 6: Architekturschema von wingS[3, S. 9]

4.2 Eventerzeugung

Fur die Eventerzeugung ist das Session-Servlet verantwortlich. Die Nachrichtendes Clients werden durch entsprechende Name-Werte Paare im Event-Dispatcherentschlusselt. Dabei entspricht der Name immer einem Oberflachenelement, und derWert gibt an, welcher Event ausgelost werden muss. Diese werden als sogenannte Low-Level-Events (LLEs) an die entsprechenden GUI-Elemente ubertragen, die sich danndarum kummern, daraus High-Level-Events (HLEs) zu generieren, die dem Anwen-der verstandlich sind. Auf diese Events wird dann reagiert, wie man dies aus Swinggewohnt ist. Es werden Listener registriert und das Verhalten im Falle eines Auftretensprogrammiert.[4, S. 28ff]

4.3 AJAX

Das dynamische Laden von Inhalten, ohne einen Reload der kompletten Seite, wirdvon wingS ebenfalls unterstutzt. Um dies nutzen zu konnen muss der Entwickler seineAnwendung nicht verandern. Durch die starke Abstraktion ubernimmt das Frameworkdie notigen Anderungen, ohne damit den Entwickler zu belasten. Damit bleibt ihm einEinarbeiten in diese Technologie erspart.

11

4.4 Beispiel

Die Programmierung unter wingS unterscheidet sich kaum von der Entwicklung einerDesktopanwendung mittels Swing. Dieses Beispiel zeigt, wie mittels eines Textfeldes einString eingelesen wird und nach einem Klick auf den OK Button dieser Wert in einemLabel angezeigt wird. Hier wird (wie auch bei Swing ublich) ein ActionListener, der furdas Setzen des Labeltextes zustandig ist, registriert.

1 import org . wings . ∗ ;2 import java . awt . event . ∗ ;3

4 public class HelloWingS {5

6 public HelloWingS ( ) {7

8 SGridLayout gr idLayout = new SGridLayout ( 1 ) ;9 SForm panel = new SForm( gridLayout ) ;

10 SLabel lName = new SLabel ( ” B i t t e geben S i e ih ren Namen e in : ” ) ;11 f ina l STextField t e x tF i e l d = new STextField ( ) ;12 SButton okButton = new SButton ( ”OK” ) ;13 gridLayout . setVgap ( 1 0 ) ;14 SLabel lH i = new SLabel ( ) ;15

16 okButton . addAct ionLis tener (new Act ionL i s t ene r ( ) {17 public void act ionPerformed ( ActionEvent e ) {18 lH i . setText ( ”Hal lo ”+t ex tF i e l d . getText ( ) ) ;19

20 } ) ;21 panel . add ( lName ) ;22 panel . add ( t ex tF i e l d ) ;23 panel . add ( okButton ) ;24 panel . add ( lHi ) ;25

26 SFrame rootFrame = new SFrame ( ) ;27 rootFrame . getContentPane ( ) . add ( panel ) ;28 rootFrame . s e tV i s i b l e ( true ) ;29 }30 }

Die restlichen Schritte um, aus dieser Anwendung eine Weboberflache zu erstellen,ubernimmt das Framework. Somit bleibt der Entwickler von der Request ResponseStruktur verschont und muss diese beim Programmdesign nicht berucksichtigen.

5 Fazit

Ereignisbasiertes Design bietet, im Gegensatz zu veralteten Request-Response Struktur,einen komfortablen Weg, Anwendungen zu erzeugen. Um Weboberflachen ereignis-basiert zu machen benotigt es allerdings vieler Umstellungen und Anpassungen. DieserAufwand ist wohl nur fur großere Projekte gerechtfertigt.

12

Da es jedoch frei verfugbare Frameworks gibt, die Desktop-GUI-Bibliotheken innahezu nichts nachstehen, kann auf eine Eigenimplementierung verzichtet werden.Durch solche Frameworks (z.B. wingS) ist es also auch fur kleine Projekte moglich,nicht auf den Komfort der ereignisbasierten Programmierung verzichten zu mussen, wasdem Entwickler ermoglicht, effizienter zu arbeiten.

Ereignisbasierte Weboberflachen sind somit (vor allem durch die Verwendungeines existierenden Frameworks) eine ernstzunehmende Alternative zu bestehendenMoglichkeiten der Webentwicklung, die bei Projekten berucksichtigt werden sollte.

6 Quellen

Literatur

[1] E. Braude. Software Design. Wiley International, 2004.

[2] G. Hohpe. Enterprise Integration Patterns. Addison-Wesley, 2003.

[3] B. Schmid. http://www.exxcellent.de/download/2006JAX-Webanwendungen_

mit_wingS2-final.pdf.

[4] S. Schuster. Diplomarbeit: Erweiterung des Web-Frameworks wingS durch die Inte-gration von optionalem Ajax. Universitat Ulm, 2003, http://wingsframework.org/doc/papers/Diplomarbeit_Stephan_Schuster.pdf.

13