Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

best practice for Undo Redo implementation [closed]

Tags:

I need to implement Undo/Redo frame work for my window application(editor like powerpoint), what should be the best practice to follow, how would be handle all property changes of my objects and it reflection on UI.

like image 489
Firoz Avatar asked Dec 16 '09 16:12

Firoz


People also ask

How is undo and redo functionality typically implemented?

In most Microsoft Windows applications, the keyboard shortcut for the undo command is Ctrl+Z or Alt+Backspace, and the shortcut for redo is Ctrl+Y or Ctrl+Shift+Z. In most Apple Macintosh applications, the shortcut for the undo command is Command-Z, and the shortcut for redo is Command-Shift-Z.

How would you implement undo/redo feature in an application?

If “UNDO” string is encountered, pop the top element from Undo stack and push it to Redo stack. If “REDO” string is encountered, pop the top element of Redo stack and push it into the Undo stack. If “READ” string is encountered, print all the elements of the Undo stack in reverse order.

Can we perform the undo/redo action more than once?

To reverse your last action, press CTRL+Z. You can reverse more than one action. To reverse your last Undo, press CTRL+Y. You can reverse more than one action that has been undone.


1 Answers

There are two classic patterns to use. The first is the memento pattern which is used to store snapshots of your complete object state. This is perhaps more system intensive than the command pattern, but it allows rollback very simply to an older snapshot. You could store the snapshots on disk a la PaintShop/PhotoShop or keep them in memory for smaller objects that don't require persistence. What you're doing is exactly what this pattern was designed for, so it should fit the bill slightly better than the Command Pattern suggested by others.

Also, an additional note is that because it doesn't require you to have reciprocal commands to undo something that was previously done, it means that any potentially one way functions [such as hashing or encryption] which can't be undone trivially using reciprocal commands can still be undone very simply by just rolling back to an older snapshot.

Also as pointed out, the command pattern which is potentially less resource intensive, so I will concede that in specific cases where:

  • There is a large object state to be persisted and/or
  • There are no destructive methods and
  • Where reciprocal commands can be used very trivially to reverse any action taken

the command pattern may be a better fit [but not necessarily, it will depend very much on the situation]. In other cases, I would use the memento pattern.

I would probably refrain from using a mashup of the two because I tend to care about the developer that's going to come in behind me and maintain my code as well as it being my ethical responsibility to my employer to make that process as simple and inexpensive as possible. I see a mashup of the two patterns easily becoming an unmaintainable rat hole of discomfort that would be expensive to maintain.

like image 136
BenAlabaster Avatar answered Oct 11 '22 03:10

BenAlabaster