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

Slides:



Advertisements
Similar presentations
Eiffel: Analysis, Design and Programming Bertrand Meyer (Nadia Polikarpova) Chair of Software Engineering.
Advertisements

© Bertrand Meyer and Yishai Feldman Notice Some of the material is taken from Object-Oriented Software Construction, 2nd edition, by Bertrand Meyer (Prentice.
Optimizing Compilers for Modern Architectures Allen and Kennedy, Chapter 13 Compiling Array Assignments.
1 Einführung in die Programmierung Introduction to Programming Prof. Dr. Bertrand Meyer Exercise Session 13.
Chair of Software Engineering Concurrent Object-Oriented Programming Prof. Dr. Bertrand Meyer Exercise Session 1: Eiffel Introduction.
Chair of Software Engineering Einführung in die Programmierung Introduction to Programming Prof. Dr. Bertrand Meyer Lecture 7: References and Assignment.
Chair of Software Engineering OOSC - Summer Semester Object-Oriented Software Construction Bertrand Meyer Lecture 3: Abstract Data Types.
Chair of Software Engineering Einführung in die Programmierung Introduction to Programming Prof. Dr. Bertrand Meyer Exercise Session 6.
Chair of Software Engineering OOSC - Summer Semester Object-Oriented Software Construction Bertrand Meyer.
Chair of Software Engineering Object-Oriented Software Construction Bertrand Meyer Lesson 16 Last update: 25 May 2004 An O-O design example.
Chair of Software Engineering Einführung in die Programmierung Introduction to Programming Prof. Dr. Bertrand Meyer Lecture 2: Dealing with Objects I.
Chair of Software Engineering OOSC Summer Semester Object-Oriented Software Construction Bertrand Meyer.
Chair of Software Engineering OOSC - Summer Semester Bertrand Meyer Object-Oriented Software Construction Lecture 8: More on inheritance.
Chair of Software Engineering ATOT - Lecture 24, 25 June Advanced Topics in Object Technology Bertrand Meyer.
Chair of Software Engineering Einführung in die Programmierung Introduction to Programming Prof. Dr. Bertrand Meyer Lecture 17: Topological Sort Algorithm.
Chair of Software Engineering Einführung in die Programmierung Introduction to Programming Prof. Dr. Bertrand Meyer Lecture 2: Dealing with Objects I.
Chair of Software Engineering Einführung in die Programmierung Introduction to Programming Prof. Dr. Bertrand Meyer Lecture 12: Introduction to inheritance.
Chair of Software Engineering ATOT - Lecture 17, 28 May Advanced Topics in Object Technology Bertrand Meyer.
Chair of Software Engineering Einführung in die Programmierung Introduction to Programming Prof. Dr. Bertrand Meyer Exercise Session 3.
Chair of Software Engineering Einführung in die Programmierung Introduction to Programming Prof. Dr. Bertrand Meyer Lecture 4: The Interface of a Class.
Chair of Software Engineering ATOT - Lecture 8, 28 April Advanced Topics in Object Technology Bertrand Meyer.
Chair of Software Engineering OOSC Summer Semester Object-Oriented Software Construction Bertrand Meyer.
Chapter 2 The Algorithmic Foundations of Computer Science
Chair of Software Engineering OOSC - Lecture 4 1 Object-Oriented Software Construction Bertrand Meyer.
Chair of Software Engineering Software Architecture Bertrand Meyer ETH Zurich, February-May 2009 Lecture 1: Introduction.
Chair of Software Engineering Einführung in die Programmierung Introduction to Programming Prof. Dr. Bertrand Meyer Lecture 4: The Interface of a Class.
Chair of Software Engineering ATOT - Lecture 9, 30 April Advanced Topics in Object Technology Bertrand Meyer.
Chair of Software Engineering Einführung in die Programmierung Introduction to Programming Prof. Dr. Bertrand Meyer Lecture 9: Abstraction.
Chair of Software Engineering Einführung in die Programmierung Introduction to Programming Prof. Dr. Bertrand Meyer Lecture 12: More on references and.
Chair of Software Engineering Einführung in die Programmierung Introduction to Programming Prof. Dr. Bertrand Meyer Exercise Session 10.
Chair of Software Engineering ATOT - Lecture 2, 2 April Advanced Topics in Object Technology Bertrand Meyer.
Chair of Software Engineering OOSC - Summer Semester Object-Oriented Software Construction Bertrand Meyer Lecture 6: Genericity.
Chair of Software Engineering ATOT - Lecture 3, 7 April Advanced Topics in Object Technology Bertrand Meyer.
1 Einführung in die Programmierung Introduction to Programming Prof. Dr. Bertrand Meyer Exercise Session 13.
Chair of Software Engineering Einführung in die Programmierung Introduction to Programming Prof. Dr. Bertrand Meyer Lecture 16: Topological sort Part 1:
Chair of Software Engineering Einführung in die Programmierung Introduction to Programming Prof. Dr. Bertrand Meyer Exercise Session 10.
Chair of Software Engineering OOSC - Summer Semester Bertrand Meyer Object-Oriented Software Construction Lecture 7: Inheritance.
Chair of Software Engineering Einführung in die Programmierung Introduction to Programming Prof. Dr. Bertrand Meyer Lecture 15: Event-driven programming.
Chair of Software Engineering Einführung in die Programmierung Introduction to Programming Prof. Dr. Bertrand Meyer Exercise Session 7.
© 2006 Pearson Addison-Wesley. All rights reserved2-1 Chapter 2 Principles of Programming & Software Engineering.
Chair of Software Engineering Einführung in die Programmierung Introduction to Programming Prof. Dr. Bertrand Meyer Lecture 12: Introduction to inheritance.
Chair of Software Engineering Einführung in die Programmierung Introduction to Programming Prof. Dr. Bertrand Meyer Lecture 20: Multiple inheritance.
Chair of Software Engineering OOSC - Summer Semester Object-Oriented Software Construction Bertrand Meyer.
Chair of Software Engineering Einführung in die Programmierung Introduction to Programming Prof. Dr. Bertrand Meyer Exercise Session 11.
Chair of Software Engineering Einführung in die Programmierung Introduction to Programming Prof. Dr. Bertrand Meyer Exercise Session 10.
Chair of Software Engineering Einführung in die Programmierung Introduction to Programming Prof. Dr. Bertrand Meyer Lecture 9: Abstraction.
Chair of Software Engineering Einführung in die Programmierung Introduction to Programming Prof. Dr. Bertrand Meyer Exercise Session 3.
© Bertrand Meyer and Yishai Feldman Notice Some of the material is taken from Object-Oriented Software Construction, 2nd edition, by Bertrand Meyer (Prentice.
Invitation to Computer Science 6th Edition
Chapter Three The UNIX Editors. 2 Lesson A The vi Editor.
Data Structures Week 4 Our First Data Structure The story so far  We understand the notion of an abstract data type.  Saw some fundamental operations.
© Bertrand Meyer and Yishai Feldman Notice Some of the material is taken from Object-Oriented Software Construction, 2nd edition, by Bertrand Meyer (Prentice.
Lexi case study (Part 2) Presentation by Matt Deckard.
Chair of Software Engineering Einführung in die Programmierung Introduction to Programming Prof. Dr. Bertrand Meyer Exercise Session 9.
1 CSCD 326 Data Structures I Software Design. 2 The Software Life Cycle 1. Specification 2. Design 3. Risk Analysis 4. Verification 5. Coding 6. Testing.
Einführung in die Programmierung Introduction to Programming Prof. Dr. Bertrand Meyer Chair of Software Engineering Complement to lecture 11 : Levenshtein.
© 2006 Pearson Addison-Wesley. All rights reserved 2-1 Chapter 2 Principles of Programming & Software Engineering.
Chair of Software Engineering Einführung in die Programmierung Introduction to Programming Prof. Dr. Bertrand Meyer Exercise Session 3.
Fall UI Design and Implementation1 Lecture 15: Undo.
Invitation to Computer Science 5 th Edition Chapter 2 The Algorithmic Foundations of Computer Science.
© Bertrand Meyer and Yishai Feldman Notice Some of the material is taken from Object-Oriented Software Construction, 2nd edition, by Bertrand Meyer (Prentice.
Programming paradigms
Chapter 10 Design Patterns.
Behavioral Design Patterns
File Handling Programming Guides.
Einführung in die Programmierung Introduction to Programming Prof. Dr
Einführung in die Programmierung Introduction to Programming Prof. Dr
Einführung in die Programmierung Introduction to Programming Prof. Dr
Introduction to Data Structure
Einführung in die Programmierung Introduction to Programming Prof. Dr
Presentation transcript:

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

2 Further reference Chapter 21 of Bertrand Meyer, Object-Oriented Software Construction, Prentice Hall, 1997 Erich Gamma et al., Design Patterns, Addison –Wesley, 1995: “Command pattern”

3 The problem Enabling users of an interactive system to cancel the effect of the last command Often implemented as “Control-Z” Should support multi-level undo-redo (“Control-Y”), with no limitation other than a possible maximum set by the user

4 Why are we doing this? Useful in every interactive application  Don’t even think of writing an interactive system without an undo-redo mechanism Useful design pattern (“Command”) Illustration of general algorithmic and data structure techniques Review of O-O techniques: inheritance, deferred classes, polymorphic data structures, dynamic binding… Beautiful and elegant

5 Our working example: a text editor Notion of “current line”. Assume commands such as:  Remove current line  Replace current line by specified text  Insert line before current position  Swap current line with next if any  Search and replace: replace every occurrence of a specified string by another ... This is a line-oriented view for simplicity, but the discussion applies to more sophisticated views.

6 Underlying class (from application*) class EDITABLE_TEXT feature text: TWO_WAY_LIST [STRING] remove -- Delete line at current position. require not off do text. remove end put_right (line: STRING) -- Insert line after current position. require not after do text. put_right (line) end... end *or “model” (cf. MVC)

7 A straightforward solution Before performing any operation, save entire state In the example: text being edited, current position in text If user issues “Undo” request, restore entire state as last saved But: huge waste of resources, space in particular! Intuition: only save the “diff” between states.

8 Key step in devising a software architecture Here: The notion of “command” Finding the right abstractions (the interesting object types)

9 Keeping the history of the session The history list: history : TWO_WAY_LIST [COMMAND] Removal Swap Insertion Oldest Most recent

10 What’s a “command” object? A command object includes information about one execution of a command by the user, sufficient to:  Execute the command  Cancel the command if requested later For example, in a Removal command object, we need:  The position of the line being removed  The content of that line!

11 General notion of command deferredclassCOMMAND feature execute -- Carry out one execution of this command. undo -- Cancel an earlier execution of this command. end deferred : done end deferred end done: BOOLEAN -- Has this command been executed? ensure already: done require already: done require not_yet: not done ensure not_yet: not done

12 Command class hierarchy execute * undo* … execute + undo + line: STRING index: INTEGER... execute + undo + new_line: STRING index: INTEGER... + * deferred effective * COMMAND + REMOVAL + INSERTION

13 Underlying class (from business model) class EDITABLE_TEXT feature text : TWO_WAY_LIST [STRING] remove -- Remove line at current position. require not off do text. remove end put_right (line : STRING) -- Insert line after current position. require not after do text. put_right (line) end... also item, index, go_ith, put_left... end

14 A command class (1) class REMOVAL inherit COMMAND feature make (t: EDITABLE_TEXT) -- Remember text, line and position. do text := t index := text.index line := text.item end text: EDITABLE_TEXT -- Access to business model. line : STRING -- Line being removed. index : INTEGER -- Position of line being removed....

15 A command class (2)... execute -- Remove current line. do text.go_i_th (index) text.remove done := True end undo -- Re-insert previously removed line. do text.go_i_th (index) text.put_left (line) done := False end

16 A polymorphic data structure: history : TWO_WAY_LIST [COMMAND] Removal Swap Insertion Oldest Most recent The history list

17 Reminder: the list of figures class LIST [G] feature... last : G do... extend (x : G) do... end fl : LIST [FIGURE] r : RECTANGLE s : SQUARE t : TRIANGLE p : POLYGON... fl. extend (p); fl. extend (t); fl. extend (s); fl. extend (r) from fl. start until fl. after loop fl. item.display; fl.forth end (SQUARE) (RECTANGLE) (TRIANGLE) (POLYGON) fl

18 Reminder: a composite figure as a list Cursor item forth

19 A polymorphic data structure: history : TWO_WAY_LIST [COMMAND] Removal Swap Insertion Oldest Most recent The history list

20 Executing a user command decode_user_request if “Request is normal command” then “Create command object c corresponding to user request” history. extend (c) c. execute elseif “Request is UNDO” then if not history. before then -- Ignore excessive requests history. item. undo history. back end elseif “Request is REDO” then if not history. is_last then -- Ignore excessive requests history. forth history. item. execute end item Pseudocode, see implementation next Removal Swap Insertion

21 Conditional creation (1) … … a1 : A if condition_1 then -- “Create a1 as an instance of B” elseif condition_2 then -- “Create a1 as an instance of 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 Conditional creation (2) a1 : A if condition_1 then -- “Create a1 as an instance of B” elseif condition_2 then -- “Create a1 as an instance of C”... etc. a1 : A if condition_1 then create {B } a1. make (...) elseif condition_2 then create {C } a1. make (...)... etc. … … A B C D

23 Executing a user command decode_user_request if “Request is normal command” then “Create command object c corresponding to user request” history. extend (c) c. execute elseif “Request is UNDO” then if not history. before then -- Ignore excessive requests history. item. undo history. back end elseif “Request is REDO” then if not history. is_last then -- Ignore excessive requests history. forth history. item. execute end item Removal Swap Insertion

24 Creating command objects: first approach c : COMMAND text: EDITABLE_TEXT... decode_user_request if “Request is remove” then create {REMOVAL } c.make (text) elseif “Request is insert” then create {INSERTION } c.make (text) else etc.

25 Command class hierarchy execute * undo* … execute + undo + line: STRING index: INTEGER... execute + undo + new_line: STRING index: INTEGER... + * deferred effective * COMMAND + REMOVAL + INSERTION

26 Creating command objects : another approach Give each command type a number Initially, fill an array commands with one instance of every command type. To get a new command object: “Determine command_type” c := (commands [command_type]). twin Removal Insertion Swap n command_type Duplicate a “prototype” commands

27 The undo-redo (or “command”) pattern Has been extensively used (e.g. in EiffelStudio and other Eiffel tools) Fairly easy to implement Details must be handled carefully (e.g. some commands may not be undoable) Elegant use of O-O techniques Disadvantage: explosion of small classes

28 Using agents For each user command, have two routines:  The routine to do it  The routine to undo it!

29 The history list in the undo-redo pattern history : TWO_WAY_LIST [COMMAND] Removal Swap Insertion Oldest Most recent

30 The history list using agents The history list simply becomes a list of agents pairs: history : TWO_WAY_LIST [TUPLE [doer : PROCEDURE [ANY, TUPLE], undoer : PROCEDURE [ANY, TUPLE]] Basic scheme remains the same, but no need for command objects any more; the history list simply contains agents. Insertion RemovalSwapInsertion De- insertion Re- insertion SwapDe- insertion Named tuple

31 Executing a user command (before) decode_user_request if “Request is normal command” then “Create command object c corresponding to user request” history. extend (c) c. execute elseif “Request is UNDO” then if not history. before then -- Ignore excessive requests history. item. undo history. back end elseif “Request is REDO” then if not history. is_last then -- Ignore excessive requests history. forth history. item. execute end item Removal Swap Insertion

32 Executing a user command (now) “Decode user_request giving two agents do_it and undo_it ” if “Request is normal command” then history.extend ([do_it, undo_it ]) do_it.call ([]) elseif “Request is UNDO” then if not history.before then history.item.undoer.call ([]) history.back end elseif “Request is REDO” then if not history.is_last then history.forth history.item.doer.call ([]) end end Insertion RemovalSwap De- insertion Re- insertion Swap

33 What we have seen People make mistakes! Even when they don’t mess up, they want to experiment: undo-redo supports “trial and error” experimental style Undo-redo pattern:  Very useful in practice  Widely used  Fairly easy to implement  Excellent illustration of elegant O-O techniques  Even better with agents!