The Design of Software (CLOSED)

A public forum for discussing the design of software, from the user interface to the code architecture. Now closed.

The "Design of Software" discussion group has been merged with the main Joel on Software discussion group.

The archives will remain online indefinitely.

Adding UNDO capability

I am developing a client/server app. using C# 2005 and SQL Server 2005. I want to add a feature in my app. to UNDO last change in a table. How to implement this feature in a way that does not create a resource hog?
RK Send private email
Thursday, August 23, 2007
Well, it will always be a resource "hog" (for sufficient values of "hog") -- you've gotta keep a command history somewhere and that history needs resources to be maintained.

Google for "command pattern undo" and you should get plenty of ideas from the results.
Thursday, August 23, 2007
BTW -- databases are particularly hard to UNDO. A single UPDATE command could change, say,  a million records in the blink of an eye. To be able to UNDO that, you've gotta store a million records somewhere with the old values.

We've implemented a generic logging structure that's trigger based. Changed values are stored in a logging table. We don't have an UNDO, per se, but we do have the ability for an administrator to "roll back" a record, or set of records, or entire table and say: "Roll these records back to what they looked like at noon, yesterday". This, IMO, is far easier to implement than a true UNDO feature for database tables.
Thursday, August 23, 2007
I'd check out Rockford Lhotka's CSLA framework:

His framework does n-level undo, but doesn't persist stuff in the DB if it's rolled back.  You may pick up some design ideas from what he's done.  Based on forum traffic, some of the intricacies of undo are a little mind-bending.

References to other objects, for instance, can get hairy, and you'll have to deal with the same thing.  Make sure, for instance, that you think about what you want to do about undoing back to a record that references another record that's been deleted in the mean time.
D. Lambert Send private email
Thursday, August 23, 2007
To expand on what Sgt.Sausage said, in order to implement undo correctly each command object needs to be able to both do and undo an action. In the case of DB activity, your code will need to account for any triggers that fire both during the initial action and the undo. This means that your undo code will be closely coupled to any triggers that you use in the database, and anyone who works on one part of the system will have to remember to make a corresponding change to the other.

If I were designing a database-backed system from the ground up with undo in mind I'd keep *all* of the business logic out of the database, and thus in one place.
Thursday, August 23, 2007
Yeah, this is the sort of thing that is best built in from the start.

As other have said, use some kind of command pattern , where each command computes/deduces the corresponding undo before application. Then keep a stack (FILO) of commands, so you can move backwards. Or, keep a dynamic array, with location pointer, then you can move back, or forwards (redo) as you wish.

Photoshop has done this really nicely for years, if you need some UI inspiration more than just an undo button.
Entries of Confusion Send private email
Friday, August 24, 2007

This topic is archived. No further replies will be accepted.

Other recent topics Other recent topics
Powered by FogBugz