views:

92

answers:

3

Hi all,

what I am trying to achieve is to have a persistent list of "undoable" changes on a persistent storage (database).

The architecture employs repositories for the domain objects and Unit of Work for transactions and for the final part (undo) I thought of using the command pattern. However, for me there seems no good solution how to make the executed command persistent.

Basically, there are 3 write-operations on repositories add/update/delete and with the command pattern I would need to store the state before the command was executed. For example: I have to store the domain object (entity) before I delete it so that I can restore it once the undo is called on the command. The big question here is how to store the before-state in a neat way!

Maybe someone of you guys came across the same question which in my mind is not that uncommon.

Thanks, Chris

A: 

The different methods that I have come across are:

  1. Store the complete domain entity before the change. This might require a complicated schema design and object-relational mapping.
  2. Store the complete domain entity before the change using an additional set of tables to hold old values.
  3. Serialize the complete domain entity before the change and store it as a BLOB or XML string.
  4. Store the change to the domain entity in a way that the undo operation can be constructed from the change. If add and update operations can create complex object graphs then you still need one of the above approaches to store the changes.
richj
hm, I guess the blob/xml approach seems appealing because of its simplicity. However, I am not 100% sure that it works out in reality but its definitely worth a prototype.The first 2 methods seem to be very vague and I guess complex as well.
balistof
The first two approaches require sophisticated designs, so it isn't practical to provide a more precise answer without a detailed description of the problem. The BLOB approach does work, however care is needed for the data to remain readable across different versions of the software.
richj
A: 

Pretty hard to give definitive advice but here are a few pointers - 0xEB67ADB1, 0xF97ACE64. Just kidding.

  1. A lot depends on your ORM. The framework that you are using can make it harder or easier. Does it require you to call a factory method to create a new entity? Or can accept a PO(J|C)O (Plain Old Java/C#/C++ Object). This makes a difference if you need to save a memento of a record before it's modified.

  2. Is there a requirement to persist IDs of the object between undo/redo operations? If you save the state of the record and then delete it and insert it, and its ID is an autoincremented primary key will be different after the insert. Might need to turn on IDENTITY_INSERT(Sql Server, I am sure there is an equivalent in other DBs and ORMs).

  3. What are the foreign key constraints? There might be a situation where the order of the operations is important.

I would be looking at either persisting the model object or some lightweight representation of it - whether it is a DTO or some other serialised form.

Igor Zevaka
A: 

Have a look at the CSLA.NET framework. It supports undo operations on domain entities, so it may be worth a look at the source for some ideas.

DanP