Programmierung im Grossen Vorlesung 13: Ereignis
Transcription
Programmierung im Grossen Vorlesung 13: Ereignis
1 Letzte Aktualisierung: 27. Mai 2004 Programmierung im Grossen Bertrand Meyer Chair of Software Engineering Programmierung im Grossen - Vorlesung 13 2 Vorlesung 13: Ereignis-Gesteuertes Design Chair of Software Engineering Programmierung im Grossen - Vorlesung 13 Ereignis-gesteuerte Programmierung Verbreiter 3 Bezieher PUBLISHERS SUBSCRIBERS löst Ereignis aus behandelt Ereignisse ROUTINE Ereignisse EVENTS ROUTINE ROUTINE Chair of Software Engineering Programmierung im Grossen - Vorlesung 13 1 Vermeiden von “glue code” 4 Ereignis Erzeuger (zB GUI) Direkte Anmeldung verbindendes Objekt Geschäfts-Modell (Anwendungs-Logik) Chair of Software Engineering Programmierung im Grossen - Vorlesung 13 Intern 5 Event-Aktions Tabelle (Genauer: Event_Typ-Aktions-Tabelle) (noch genauer: Kontext- Event_Typ-AktionsTabelle) Event Typ Aktion Left_click Save_file … Chair of Software Engineering … Programmierung im Grossen - Vorlesung 13 Ereignis-gesteuerte Programmierung Verbreiter 6 Bezieher PUBLISHERS SUBSCRIBERS löst Ereignis aus behandelt Ereignisse ROUTINE Ereignisse EVENTS ROUTINE ROUTINE Chair of Software Engineering Programmierung im Grossen - Vorlesung 13 2 Ereignis-Bibliothek (Event Library) 7 Klasse EVENT_TYPE Publisher Seite, zB GUI Bibliothek: (Einmal) deklariere Event-Typ: click: EVENT_TYPE [TUPLE [INTEGER, INTEGER]] (Einmal) erzeuge ein Event-Typ Objekt: create click Jedesmal wenn das Ereignis eintritt: click.publish ([x_coordinate, y_coordinate]) Subscriber Seite: click.subscribe (agent my_procedure) Chair of Software Engineering Programmierung im Grossen - Vorlesung 13 Subscriber Varianten 8 click.subscribe (agent my_procedure) my_button.click.subscribe (agent my_procedure) click.subscribe (agent your_procedure (a, ?, ?, b)) click.subscribe (agent other_object.other_procedure) Chair of Software Engineering Programmierung im Grossen - Vorlesung 13 EiffelVision style 9 my_button.click.action_list.extend (agent my_procedure) Chair of Software Engineering Programmierung im Grossen - Vorlesung 13 3 Observer pattern (C++, Java) update* * SUBSCRIBER update+ * attach detach PUBLISHER APPCLASS * Deferred (abstrakt) + Effective (implementiert) Chair of Software Engineering 10 LIBCLASS erbt von Client (verwendet) Programmierung im Grossen - Vorlesung 13 Observer Pattern 11 In PUBLISHER: subscribed: LIST [SUBSCRIBER] -- Klienten subscriben bei diesem Publisher attach (s: SUBSCRIBER) is -- Speichern der subscription von s. do subscribed.extend (s) end publish is do -- Auslösen des Events. from subscribed.start until subscribed.after loop subscribed.item.update subscribed.forth end end Chair of Software Engineering Programmierung im Grossen - Vorlesung 13 Observer Pattern 12 In SUBSCRIBER: subscribe (p: PUBLISHER) is -- p’s events subscriben. do p.attach (Current) end Chair of Software Engineering Programmierung im Grossen - Vorlesung 13 4 Observer Pattern 13 In SUBSCRIBER: subscribe (p: PUBLISHER) is -- p’s events subscriben. require publisher_exists: p /= Void do p.attach (Current) end Chair of Software Engineering Programmierung im Grossen - Vorlesung 13 Observer Pattern 14 grundsätzlich: Publisher kennen Subscriber Subscriber können sich höchstens bei einem Publisher anmelden Dürfen sich höchstens für eine Aktion anmelden Nicht wieder verwendbar — muss für jede Anwendung neu programmiert werden Chair of Software Engineering Programmierung im Grossen - Vorlesung 13 Event Library 15 Publisher, z.B. GUI Library: Deklaration und Creation: click: EVENT_TYPE [TUPLE [INTEGER, INTEGER]] Auslösen des Events mit Argumenten. click.publish ([x, y]) Subscriber: my_button.click.subscribe (agent r) Chair of Software Engineering Programmierung im Grossen - Vorlesung 13 5 Observer pattern (C++, Java) update* * SUBSCRIBER update+ * attach detach APPCLASS * Deferred (abstrakt) + Effective (implementiert) Chair of Software Engineering PUBLISHER LIBCLASS erbt von Client (verwendet) Programmierung im Grossen - Vorlesung 13 Hintergrundinformation: .NET 16 17 Basis für zukünftige Windows Entwicklung Seit 2000 Schicht über dem Betriebsystem Unterstützt fortgeschrittene Web Technologien, speyiell durch ASP.NET Basiert auf einem Object Modell Microsoft Sprachen: C#, Visual Basic .NET Andere unterstützte Sprachen: Eiffel, Cobol, Oberon Zahlreiche Bibliotheken und wieder verwendbare Komponenten Internationaler Standard (Common Language Interface) durch ECMA und ISO Nicht-Windows Implementation: Mono Chair of Software Engineering Programmierung im Grossen - Vorlesung 13 .NET Event-Delegate Mechanismus 18 Publisher oder Subscriber: D1 Führe einen Nachfahren ClickArgs von EventArgs ein, der die Typen der Argumente von myProcedure wiederholt. (Fügt eine Klasse hinzu.) public class ClickArgs { int x, y;... } D2 Deklariere einen Delegate-Typ ClickDelegate basierend auf dieser Klasse. (Fügt einen Typ hinzu.) public void delegate ClickDelegate (Object sender, ClickArgs e); Chair of Software Engineering Programmierung im Grossen - Vorlesung 13 6 .NET Delegates: Publisher 19 D3 Deklariere einen neuen Event-Typ Click basierend auf dem Typ ClickDelegate. (Fügt einen Typ hinzu.) public event ClickDelegate Click; D4 Schreibe Prozedur OnClick für die Behandlung. (+ 1 Routine.) protected void OnClick (ClickArgs e) { if (Click != null) Click (this, e); } D5 Für jedes Auftreten des Events erzeuge eine Instanz von ClickArgs und übergebe arg Werte an den Konstruktor. (Fügt ein Laufzeit-Objekt hinzu.) ClickArgs myClickArgs = new ClickArgs (h, v); D6 Für jedes Auftreten, feure den Event OnClick (myClickArgs); Chair of Software Engineering Programmierung im Grossen - Vorlesung 13 .NET Delegates: Subscriber 20 Um eine Routine myProcedure anzumelden: D7 Deklariere einen Delegate myDelegate vom Typ ClickDelegate. (Kann mit dem folgenden Schritt kombiniert werden.) D8 Instanziiere es mit myProcedure als Konstruktor-Argument. ClickDelegate myDelegate = new ClickDelegate (myProcedure) D9 Füge es der Delegate-Liste für den Event hinzu. yourButton.Click += myDelegate Chair of Software Engineering Programmierung im Grossen - Vorlesung 13 .NET Delegates 21 event ist ein Schlüsselwort der Sprache (besonderes Feature einer Klasse). Event-Typen sollten aber wie normale Objekte behandelt werden. Kann keine geschlossene Argumente haben: für etwas Equivalentes zu r (a, ?, ?, b) muss man eine Wrapper-Routine schreiben, die vom Delegate verwendet wird. Kann kein offenes Ziel haben: für etwas wie {TYPE}.r (...) muss man eine Wrapper-Routine schreiben. Chair of Software Engineering Programmierung im Grossen - Vorlesung 13 7 Event library 22 Publisher, e.g. GUI library: Declare and create: click: EVENT_TYPE [TUPLE [INTEGER, INTEGER]] Trigger each event with arguments. click.publish ([x, y]) Subscriber (to subscribe a routine r): my_button.click.subscribe (agent r) Chair of Software Engineering Programmierung im Grossen - Vorlesung 13 Gelerntes 23 Vermeide Magie: Was für den Sprach-Designer verfügbar ist, sollte für den Programmierer verfügbar sein Rolle der Sprach-Mechanismen: Generizität, beschränkte Generizität, Tupel Wichtig, die richtige Abstraktion zu wählen Observer Pattern: PUBLISHER, SUBSCRIBER .NET: Event, Delegate, Event-Typ, DelegateTyp? Eiffel Event Bibliothek: EVENT_TYPE Chair of Software Engineering Programmierung im Grossen - Vorlesung 13 Vermeiden von “glue code” 24 Ereignis Erzeuger (zB GUI) Direkte Anmeldung verbindendes Objekt Geschäfts-Modell (Anwendungs-Logik) Chair of Software Engineering Programmierung im Grossen - Vorlesung 13 8 Zusätzliches Material 25 Eiffel: The Language, 3rd Auflage (Entwurf), Kapitel 25 → Erhältlich http://www.inf.ethz.ch/~meyer/ongoing/etl/agent.pdf (Login: Talkitover; Passwort: etl3) Paper über Event-basierte Programmierung → Erhältlich http://www.inf.ethz.ch/~meyer/ongoing/events.pdf Chair of Software Engineering Programmierung im Grossen - Vorlesung 13 26 Ende Vorlesung 13 Chair of Software Engineering Programmierung im Grossen - Vorlesung 13 9