Chair of Software Engineering Einführung in die Programmierung Prof. Dr. Bertrand Meyer Lecture 18: Undo/Redo.

Slides:



Advertisements
Ähnliche Präsentationen
Vorbereitung zu Praktikum 3
Advertisements

Algorithmentheorie 08 – Dynamische Programmierung (1)
Kap. 13 Sweep-Line Algorithmen Kap Schnittprobleme
Programmierung II Prof. Dr. Michael Löwe
WS Prof. Dr. Th. Ottmann Algorithmentheorie 09 - Suche in Texten KMP, BM.
Vorgehensweise Website Besprechung am 11. Februar 2008 Gründung und Partnerunternehmen der Wirtschaftsuniversität Wien.
Finale Semantik und beobachtbares Verhalten
Gliederung Motivation / Grundlagen Sortierverfahren
Sortierverfahren Richard Göbel.
Java: Dynamische Datentypen
Listen Richard Göbel.
Sortierverfahren Richard Göbel.
WS Algorithmentheorie 05 - Treaps Prof. Dr. Th. Ottmann.
Prinzipien des Algorithmenentwurfs Backtracking Prof. Dr. Th. Ottmann
Vorlesung Informatik 2 Algorithmen und Datenstrukturen (13 – Offenes Hashing) Prof. Th. Ottmann.
Vorlesung Informatik 2 Algorithmen und Datenstrukturen (05 – Elementare Datenstrukturen) Prof. Th. Ottmann.
Informatik II, SS 2008 Algorithmen und Datenstrukturen Vorlesung 6 Prof. Dr. Thomas Ottmann Algorithmen & Datenstrukturen, Institut für Informatik Fakultät.
PRJ 2007/1 Stefan Dissmann Motivation Problem: gleiche Datenstrukturen werden für verschiedene Objekte gebraucht: z.B. Listen von Studierenden, Kunden,
PKJ 2005/1 Stefan Dissmann Rückblick auf 2005 Was zuletzt in 2005 vorgestellt wurde: Klassen mit Attributen, Methoden und Konstruktoren Referenzen auf.
Command Pattern Karola Schäuble,
Einführung in die Programmierung Datensammlung
Prof. Dr. Gerhard Schmidt pres. by H.-J. Steffens Software Engineering SS 2009Folie 1 Objektmodellierung Objekte und Klassen Ein Objekt ist ein Exemplar.
Einführung in die Programmierung
Ich möchte gerne mehrere Bilder auf ein Folie
Einführung in die Programmierung Prof. Dr. Bertrand Meyer
Chair of Software Engineering Einführung in die Programmierung Prof. Dr. Bertrand Meyer Lektion 14: Mehrfachvererbung.
Chair of Software Engineering Einführung in die Programmierung Prof. Dr. Bertrand Meyer Lecture 13: (Container-)Datenstrukturen.
Einführung in die Informatik für Naturwissenschaftler und Ingenieure (alias Einführung in die Programmierung) (Vorlesung) Prof. Dr. Günter Rudolph Fachbereich.
Einführung in die Programmierung
Chair of Software Engineering Einführung in die Programmierung Prof. Dr. Bertrand Meyer Lecture 13: (Container-)Datenstrukturen.
Einführung in die Informatik für Naturwissenschaftler und Ingenieure
Einführung in die Informatik für Naturwissenschaftler und Ingenieure
Einführung in die Programmierung Wintersemester 2008/09 Prof. Dr. Günter Rudolph Lehrstuhl für Algorithm Engineering Fakultät für Informatik TU Dortmund.
Einführung in die Informatik für Naturwissenschaftler und Ingenieure (alias Einführung in die Programmierung) (Vorlesung) Prof. Dr. Günter Rudolph Fachbereich.
Einführung in die Programmierung Wintersemester 2009/10 Prof. Dr. Günter Rudolph Lehrstuhl für Algorithm Engineering Fakultät für Informatik TU Dortmund.
Einführung in die Informatik für Naturwissenschaftler und Ingenieure (alias Einführung in die Programmierung) (Vorlesung) Prof. Dr. Günter Rudolph Fakultät.
Einführung in die Informatik für Naturwissenschaftler und Ingenieure (alias Einführung in die Programmierung) (Vorlesung) Prof. Dr. Günter Rudolph Fakultät.
Einführung in die Informatik für Naturwissenschaftler und Ingenieure (alias Einführung in die Programmierung) (Vorlesung) Prof. Dr. Günter Rudolph Fachbereich.
Einführung in die Programmierung
Chair of Software Engineering Einführung in die Programmierung Prof. Dr. Bertrand Meyer Lektion 11: Einführung in die Konzepte der Vererbung und Generizität.
Informatik 1 Letzte Übung.
Chair of Software Engineering Einführung in die Programmierung Prof. Dr. Bertrand Meyer Lektion 15: Topologisches Sortieren Teil 1: Problemstellung und.
Chair of Software Engineering Einführung in die Programmierung Prof. Dr. Bertrand Meyer Lektion 9: Abstraktion.
Einführung in die Programmierung Prof. Dr. Bertrand Meyer
Chair of Software Engineering Einführung in die Programmierung Prof. Dr. Bertrand Meyer Lecture 10: Das dynamische Modell und mehr zu Referenzen.
Chair of Software Engineering Einführung in die Programierung Prof. Dr. Bertrand Meyer Lektion 8: Kontrollstrukturen.
Chair of Software Engineering Einführung in die Programmierung Prof. Dr. Bertrand Meyer Lektion 14: Mehrfachvererbung.
Wie schreibe ich eine Diplom- bzw. Masterarbeit ?
Chair of Software Engineering Einführung in die Programmierung Prof. Dr. Bertrand Meyer Lektion 7: Referenzen und Zuweisungen.
Chair of Software Engineering Einführung in die Programmierung Prof. Dr. Bertrand Meyer Lektion 4: Die Schnittstelle einer Klasse.
Einführung in die Programmierung Prof. Dr. Bertrand Meyer
Programiersprache Mustafa SÖYLEMEZ e
Chair of Software Engineering Einführung in die Programmierung Prof. Dr. Bertrand Meyer Lektion 11: Einführung in die Konzepte der Vererbung und Generizität.
Agenda für heute, 7. April, 2005 Bedingte ProgrammausführungBedingte Programmausführung Algorithmische Grundlagen Vergleichsoperatoren, Wahrheitswerte.
Chair of Software Engineering Einführung in die Programmierung Prof. Dr. Bertrand Meyer Lektion 18: Mehr über Vererbung und Agenten.
Einführung in die Programmierung Prof. Dr. Bertrand Meyer
Mag. Thomas Hilpold, Universität Linz, Institut für Wirtschaftsinformatik – Software Engineering 1 Algorithmen und Datenstrukturen 1 SS 2002 Mag.Thomas.
Mag. Thomas Hilpold, Universität Linz, Institut für Wirtschaftsinformatik – Software Engineering 1 Algorithmen und Datenstrukturen 1 SS 2002 Mag.Thomas.
Java-Kurs Übung Besprechung der Hausaufgabe Vererbung
Institut für Kartographie und Geoinformation Prof. Dr. Lutz Plümer Diskrete Mathematik II Vorlesung Datenstrukturen für den Algorithmus von.
Java-Kurs Übung Besprechung der Hausaufgabe Vererbung
Chair of Software Engineering Einführung in die Programmierung Prof. Dr. Bertrand Meyer Lektion 17: Ereignisorientierte Programmierung und Agenten.
Objektorientierte Programmierung (OOP)
Tabellen im Word Als erstes müsst ihr das Microsoft Word starten.
Funktionen. Aufgabe : Eingabe zweier Zahlen ---> Minimum bestimmen Dann nochmals Eingabe zweier Zahlen ---> Minimum bestimmen.
Programmiersprachen II Fortsetzung Datenstrukturen Hashing Prof. Dr. Reiner Güttler Fachbereich GIS HTW.
Chair of Software Engineering Einführung in die Programmierung Prof. Dr. Bertrand Meyer Lektion 11:Einführung in die Konzepte der Vererbung und Generizität.
Programmiersprachen II Graph_Algorithmen Einführung Prof. Dr. Reiner Güttler Fachbereich GIS HTW.
Chair of Software Engineering Einführung in die Programmierung Prof. Dr. Bertrand Meyer Lecture 10: Das dynamische Modell und mehr zu Referenzen.
Einführung in die Programmierung Prof. Dr. Bertrand Meyer
 Präsentation transkript:

Chair of Software Engineering Einführung in die Programmierung Prof. Dr. Bertrand Meyer Lecture 18: Undo/Redo

2 Weiterführende Referenzen Kapitel 21 meines Object-Oriented Software Construction, Prentice Hall, 1997 Erich Gamma et al., Design Patterns, Addison –Wesley, 1995: “Command pattern”

3 Die Problemstellung Dem Benutzer eines interaktiven Systems die Möglichkeit geben, die letzte Aktion rückgängig zu machen. Bekannt als “Control-Z” Sollte mehrstufiges rückgängig Machen (“Control-Z”) und Wiederholen (“Control-Y”) ohne Limitierung unterstützen, ausser der Benutzer gibt eine maximale Tiefe an.

4 Wieso machen wir das? Nützlich in jeder interaktiven Anwendung  Denken Sie nicht einmal daran, ein interaktives System ohne Undo/Redo-Mechanismus zu schreiben. Nützliches Entwurfsmuster (“Command-Pattern”) Illustration genereller Algorithmik und Datenstrukturen Ein Rückblick auf O-O-Techniken: Vererbung, aufgeschobene Klassen, polymorphe Datenstrukturen, dynamisches Binden… Schön und elegant

5 In unserem Beispiel: Ein Texteditor Begriff der „aktuellen Zeile“ mit folgenden Befehlen:  Löschen der aktuellen Zeile  Ersetzen der aktuellen Zeile mit einer anderen  Einfügen einer Zeile vor der aktuellen Position  Vertauschen der aktuellen Zeile mit der nächsten (falls vorhanden)  „Globales Suchen und Ersetzen“ (fortan GSE): Jedes Auftreten einer gewissen Zeichenkette durch eine andere ersetzen. ... Dies ist eine Zeilen-orientierte Ansicht aus Einfachheitsgründen, aber die Diskussion kann auch auf kompliziertere Ansichten angewendet werden.

6 Zugrundeliegende Klasse (aus dem Modell; vgl MVC) class EDIT_CONTROLLER feature text : TWO_WAY_LIST [STRING] remove -- Lösche Linie an aktueller Position. require not off do text. remove end put_right (line : STRING) -- Füge line nach der aktuellen Position ein. require not after do text. put_right (line) end... Auch: item, index, go_ith, put_left... end

7 Eine einfache Lösung Sichern des gesamten Zustandes vor jeder Operation. Im Beispiel: Der Text, der bearbeitet wird und die aktuelle Position im Text. Wenn der Benutzer ein „Undo“ verlangt, stelle den zuletzt gesicherten Zustand wieder her. Aber: Verschwendung von Ressourcen, im speziellen Speicherplatz. Intuition: Sichere nur die Änderungen (diff) zwischen zwei Zuständen.

8 Schlüsselschritt im Entwerfen einer Software-Architektur Hier: Der Begriff eines “Befehls” Die richtigen Abstraktionen finden (die interessanten Objekt-Typen)

9 Die „History“ einer Sitzung speichern Die History-Liste: history : TWO_WAY_LIST [COMMAND] Löschen Austauschen Einfügen Am Ältesten Am Neusten

10 Was ist ein “Command”-Objekt? Ein „Command“-Objekt beinhaltet genügend Informationen über eine Ausführung eines Befehls durch den Benutzer, um  den Befehl auszuführen  den Befehl rückgängig zu machen Beispiel: In einem “Löschungs”-Objekt brauchen wir: Die Position der zu löschenden Zeile Den Inhalt dieser Zeile!

11 Genereller Begriff eines Befehls (Klasse COMMAND) deferredclassCOMMAND feature execute -- Befehl einmal ausführen. undo -- Frühere Ausführung rückgängig machen. end deferred : done end deferred end done: BOOLEAN -- Wurde dieser Befehl ausgeführt? ensure already: done require already: done require not_yet: not done ensure not_yet: not done

12 Hierarchie der Befehlsklassen execute * undo* … execute + undo + line: STRING index: INTEGER... execute + undo + new_line: STRING index: INTEGER... + * aufgeschoben wirksam * COMMAND + REMOVAL + INSERTION

13 Zugrunde liegende Klasse class EDIT_CONTROLLER feature text : TWO_WAY_LIST [STRING] remove -- Lösche Linie an aktueller Position. require not off do text. remove end put_right (line : STRING) -- Füge line nach der aktuellen Position ein. require not after do text. put_right (line) end... Auch: item, index, go_ith, put_left... end

14 Eine Befehlsklasse (1) class REMOVAL inherit COMMAND feature make (t: EDITABLE_TEXT) -- Speichere Text, Linie und Position do text := t index := text.index line := text.item end text: EDITABLE_TEXT -- Zugriff zum Geschäftsmodell. line : STRING -- Zu löschende Linie. index : INTEGER -- Position der zu löschenden Linie....

15 Eine Befehlsklasse (2)... execute -- Lösche aktuelle Linie. do text.go_i_th (index) text.remove done := True end undo -- Wiedereinfügen einer gelöschten Linie do text.go_i_th (index) text.put_left (line) done := False end

16 Die „History“ einer Sitzung speichern Eine polymorphe Datenstruktur: history : TWO_WAY_LIST [COMMAND] Löschen Austauschen Einfügen Am Ältesten Am Neusten

17 Erinnerung: Die Liste von Figuren class LIST [G] feature... last : G do... extend (x : G) do... end fl : LIST [FIGUR] r : RECHTECK q : QUADRAT d : DREIECK p : POLYGON... fl. extend (p); fl. extend (d); fl. extend (q); fl. extend (r) from fl. start until fl. after loop fl. item.display; fl.forth end (QUADRAT) (RECHTECK) (DREIECK) (POLYGON) fl

18 Erinnerung: Eine zusammengesetzte Figur als Liste Cursor item forth

19 Die History-Liste Eine polymorphe Datenstruktur: history : TWO_WAY_LIST [COMMAND] Löschen Austauschen Einfügen Am Ältesten Am Neusten

20 Einen Benutzerbefehl ausführen decode_user_request if “Anfrage ist ein normaler Befehl” then “Erzeuge ein Befehlsobjekt c, der Anforderung entsprechend” history. extend (c) c. execute elseif “Anfrage ist UNDO” then if not history. before then -- Ignoriere überschüssige Anfragen history. item. undo history. back end elseif “Anfrage ist REDO” then if not history. is_last then – Ignoriere überschüssige Anfragen history. forth history. item. execute end item Pseudocode, siehe nächste Implementation Löschen Austauschen Einfügen

21 Bedingte Erzeugung (1) … … a1 : A if condition_1 then -- “Erzeuge a1 als Instanz von B” elseif condition_2 then -- “Erzeuge a1 als Instanz von C”... etc. a1 : A; b1 : B ; c1 : C ; d1 : D ;... if condition_1 then create b1. make (...) a1 := b1 elseif condition_2 then create c1. make (...) a1 := c1... etc. A B C D

22 Bedingte Erzeugung (2) … … a1 : A if condition_1 then create {B } a1. make (...) elseif condition_2 then create {C } a1. make (...)... etc. A B C D a1 : A if condition_1 then -- “Erzeuge a1 als Instanz von B” elseif condition_2 then -- “Erzeuge a1 als Instanz von C”... etc.

23 Einen Benutzerbefehl ausführen decode_user_request if “Anfrage ist ein normaler Befehl” then “Erzeuge ein Befehlsobjekt c, der Anforderung entsprechend” history. extend (c) c. execute elseif “Anfrage ist UNDO” then if not history. before then -- Ignoriere überschüssige Anfragen history. item. undo history. back end elseif “Anfrage ist REDO” then if not history. is_last then -- Ignoriere überschüssige Anfragen history. forth history. item. execute end item Löschen Swap Einfügen

24 Befehlsobjekte erzeugen: Erster Ansatz c : COMMAND... decode_user_request if “Anfrage ist remove” then create {REMOVAL } c elseif “Anfrage ist insert” then create {INSERTION } c else etc.

25 Hierarchie der Befehlsklassen execute * undo* … execute + undo + line: STRING index: INTEGER... execute + undo + index... + * aufgeschoben wirksam * COMMAND + REMOVAL + INSERTION

26 Befehlsobjekte erzeugen: Besserer Ansatz Geben Sie jedem Befehl-Typ eine Nummer Füllen Sie zu Beginn einen Array commands mit je einer Instanz jedes Befehls-Typen. Um neue Befehlsobjekte zu erhalten: “Bestimme command_type” c := (commands [command_type]). twin Removal Insertion Swap n command_type Einen “Prototypen” duplizieren commands

27 Das Undo/Redo (oder Command-) Pattern Wurde extensiv genutzt (z.B. in EiffelStudio und anderen Eiffel-Tools) Ziemlich einfach zu implementieren Details müssen genau betrachtet werden (z.B. sind manche Befehle nicht rückgängig machbar) Eleganter Gebrauch von O-O-Techniken Nachteil: Explosion kleiner Klassen

28 Der Gebrauch von Agenten Für jeden Benutzerbefehl haben wir zwei Routinen:  Die Routine, um ihn auszuführen  Die Routine, um ihn rückgängig zu machen

29 Die History-Liste im Undo/Redo-Pattern history : TWO_WAY_LIST [COMMAND] Am Ältesten Am Neusten Löschen Swap Einfügen

30 Die History-Liste mit Agenten Die History-Liste wird einfach zu einer Liste von Agentenpaaren: history : TWO_WAY_LIST [TUPLE [doer : PROCEDURE [ANY, TUPLE], undoer : PROCEDURE [ANY, TUPLE]] Das Grundschema bleibt dasselbe, aber man braucht nun keine Befehlsobjekte mehr; die History-Liste ist einfach eine Liste, die Agenten enthält. Einfügen LöschenSwap Einfügen Wieder Entfernen Wieder Einfügen Swap Wieder Entfernen Benanntes Tupel

31 Einen Benutzerbefehl ausführen (vorher) decode_user_request if “Anfrage ist normaler Befehl” then “Erzeuge ein Befehlsobjekt c, der Anforderung entsprechend” history. extend (c) c. execute elseif “Anfrage ist UNDO” then if not history. before then -- Ignoriere überschüssige Anfragen history. item. undo history. back end elseif “Anfrage ist REDO” then if not history. is_last then – Ignoriere überschüssige Anfragen history. forth history. item. execute end item Löschen Swap Einfügen

32 Einen Benutzerbefehl ausführen (jetzt) “Dekodiere Benutzeranfrage mit zwei Agenten do_it and undo_it ” if “Anfrage ist normaler Befehl” then history. extend ([do_it, undo_it ]) do_it. call ([]) elseif “Anfrage ist UNDO” then if not history. before then history. item. undoer. call ([]) history. back end elseif “Anfrage ist REDO” then if not history. is_last then history. forth history. item. doer. call ([]) end end Insertion RemovalSwap De- insertion Re- insertion Swap

33 Was wir gesehen haben Menschen machen Fehler! Auch wenn sie keine Fehler machen: sie wollen experimentieren. Undo/Redo unterstützt einen „trial and error“-Stil. Undo/Redo-Pattern:  Sehr nützlich in der Praxis  Weit verbreitet  Ziemlich einfach zu implementieren  Exzellentes Beispiel von eleganten O-O-Techniken  Mit Agenten noch besser!