I respectfull dissagree,
all other changes are in my experiance easy. (I have written a complex CAD System and a CASE system my own)
You have only 4 kinds of commands:
* creation
* deletion
* attribute change
* linking -- a special case of attribute change
Linking is more complex as it can fall into three subgroupes:
* create new and link (drawing a new connector causes about 4 new links)
* unlink and create new and link (typing a new stereotype over an existing one or relink an end of a connection to a different classifier)
* unlink old and link existing (replacing a type for an attribute or return type of an method with a different one or moving a classifier into a different package)
The more complex ones only change two or more attributes, while the simpler ones change just one, or create/delete something.
The problem you see might come from redoing commands in a unknown or free order. But thats not needed(and likely not wanted).
As long as commands are executed sequencialy by the user, they get stored in a kind of double linked queue, so you can move with a curser forward and backward. Undoing is only possible sequencialy as well, while the cursor is moved backward towards the beginning of the queue. Redoing is only possible forwards by moving the cursor in direction of the end of the queue. There exist no unforseeable side effects between undoing/redoing as they are executed in their order of dependency.
If a command causes cascading effects, usually only happening if you move a class from one package to the other or you delete a classifier and all links need to get deleted as well, affecting other classifiers, you create a composite command and group all commands together.
Now we have only one problem: interaction of several users working simultaniously, maintaning one shared comand queue or seperated queues? That means the DB should probably be cleaned up after the last one loggs off?
A database problem I see: DB generated IDs. Deleting a classifier and removing it from the DB and later redoing its creation might cause it to get a different key/ID. Thats why I mark deleted objects only as deleted and keep them as long as I think they might get revived.
Anyway: if you had the command pattern implemented and the commands persistant, long time persistant not only per session, stuff like versioning and historization would become trivial as well.
Imagine to roll a view of a diagramm one week back.
In our days a complete command log is no memory issue anymore ... and if you fear the memory usage indeed, then start throwing away commands older than a week, or two, or 6 monthes.
A complete command log would be a uique selling point for EA ... as far as I know. (As my CASE system never made it to the market as my company went bancrupt :-/ in 1999 and I never saw another system supporting it)
Oh, yes, in case you consider to go for that: I seperated commands wich only had view effects, like alligning all classes vertically, from commands changing the model. The view history was thrown away after the user switched to an other diagram, only the model changes where kept.
Regards,
angel'o'sphere