First I need to state the obvious…some actions can’t be undone. That being said for all other actions there is an advanced concept that Greg Young talks about called DDDD (Distributed Domain Driven Design). The basic gist is…everything that occurs within your system occurs through a recordable and reversible message (a command if you will). At any point those messages can be “committed”/saved/persisted/ what have you and from there out all new messages go against the new baseline of your system. Think of it as how SQL Server does a backup log. Every action within SQL Server gets logged, when you make a backup, the log is cleared.
So now your domain model consists of the commands that can be performed (against your original domain model)
Take for example a simple drawing app. Some commands might be:
draw line from point a to point b with color c
draw rectangle with upper left corner a and lower right corner b
draw ellipse with bounding rectangle x
apply gradient to object y with these settings
add stop to gradient z
You get the picture. Once you have this, the game gets interesting because you can do a basic stack (last in first out) where a user can undo one command at a time until he gets to a specific one. Or you can allow the user to choose individual commands to “forget” Retaining the others.
If you’d like to discuss more, I love the topic. So feel free to fire a message.
--Mike
FWIW I love how Paint.NET is doing undo/redo, by displaying the stack of operations and showing you which operations are available for undo/redo. This is a cool visualization to what Mike is describing below!
Cheers,
Laurent