I was talking with my friend last night on the way back from London about my editor and how I implemented undos and redos. My initial quote was "use memento pattern", but I'm not quite sure this is right now, as the technique I used extended the idea a little and touched the "command" pattern too.
What I've done is simply base class all model operations with a command class and made all commands push themselves onto a done stack. Undo commits the undo method of the top of the undo stack into the model, then pushes that item onto a redo stack, and pops the undo stack.
Redo just reverses the operation and commits the redo method on the model instead. The command is it's own memento.
This way of working was important for me because I wanted (eventually) to be able to save commands to disk as I was working. This was to be my uncrashable editor. Or at least very easily debuggable editor.
Having recently played with SQLlite, I'm thinking of using a database like this to store my commands as well as the data. It's well known to be safe from crashes and general corruption problems so should be the basis of a very safe editor system.
If a crash happens, I should be able to just load up the last session, and replay the commands issued up to the point of the crash, which should allow me to debug even final release code by having repeatability.
But the thing that came to me last night was more useful than just that. Being able to replay commands is useful in at least two other ways. Firstly, we have a database of the commands that are used to do jobs. We can replay the actions of a user (even the undos and redos if that's part of the saved structure), and learn about what actions could be done quicker if there were macros or combination actions that did more than what's currently available.
Think of it like sample profiling, find out what the user is spending most of their time on and optimise the operation so it takes less time, or can be automated.
The other thing, by adding other metrics to the commands such as when they were done/called, we can find out which users are most productive, and learn techniques from them. We can learn how to shortcut (minimal actions or time to do a task), and learn about how they get into flow (time between commands). Although this would probably feel like an invasion of privacy to some people in a professional environment, I'm actually a bit fired up at the idea of "time and motion" being done inside the tool you're using. There's nothing wrong with making your job easier!