N-level undo as decorated functionality

N-level undo as decorated functionality

Old forum URL: forums.lhotka.net/forums/t/2797.aspx


MyklKelsey posted on Sunday, April 29, 2007

This may be a foolish question - but I would be interested in what responses are out there.

It seems to me that the ramifications of implementing n-level undo is sprinkled throughout the classes in the CSLA.  This is heavy weight functionality that isn't always needed or used.  I was wondering if any thought has been given to factoring out that functionality and allow it to be plugged in only if needed.  This could be done with a decorator, or possibly by having an interface that could be implemented to allow the functionality.  This same architecture could then be extended to "plug or unplug" other functionality as needed.

Maybe this is so ingrained that altering the CSLA isn't possible and do it ourself from the ground up is the only answer to have a common framework without the n-level undo functionality intertwined.  Has this already been considered?  What are some thoughts on our options?

The reason I ask is because our development team is interested in working off of a common framework on all the small disparate project we build/support and CSLA is one such framework being considered.  The biggest concern being voiced is carrying along functionality that isn't needed - n-level undo is the example thrown up to dismiss CSLA as an option.  I find myself in a position to be championing CSLA as our option.  So I'm looking to the forum for some ammunition to bolster my position that CSLA will have more benefits than the learning curve and the inconvenience of extraneous coding in all properties etc. for the unused functionality.

Thanks for any help you can provide.

- Michael

RockfordLhotka replied on Monday, April 30, 2007

I assume you are doing web development, because if you are doing Windows or WPF development using data binding then you can't actually live without the undo capability. Especially in Windows data binding, things just won't work right without it.

If you are doing web development (or web-like WPF development to be fair), then n-level undo incurs no overhead if you don't call BeginEdit/CancelEdit/ApplyEdit. While it is true that things like the NotUndoable attribute are used in other classes, that attribute is only used when one of the three n-level undo methods are invoked.

In fact, due to the way the .NET just-in-time compiler works, the code in UndoableBase isn't even compiled in most web scenarios, because in .NET, methods are only compiled when invoked. If you don't invoke the n-level undo methods, they never even get compiled or loaded in memory. Pretty cool stuff! Smile [:)]

The other place you may see "overhead" is in the interaction between collections and their children. In particular, in the tracking of a parent reference and cascading events. While these behaviors are useful for n-level undo, they are also useful for many business logic scenarios involving validation logic, etc. So even if you removed UndoableBase from the equation, you'd almost certainly need to leave these behaviors intact, or manually implement them yourselves in your classes...

Yet another thing to consider is this: for most web apps the transaction volume isn't really that high, and so a normal OO design approach can be taken to build your objects. In a minority of cases the transaction volume may be very high (MySpace, etc.) and in that case you may need to create a "bastardized" object model.

I've discussed that effect in other threads on this forum before. If you can avoid the bastardized model you'll be happier, because your code will be much simpler to write and maintain. But if you can't, then you never have parent-child object relationships at all. The "child" objects end up enforcing rules that would have come naturally from the object model itself, or from the parent object - which is why this is much harder to implement. However, the upside is that all objects become root objects and thus load and save faster - on a per-page basis.

The result is a more expensive, harder to maintain app, but one that can handle much higher transaction volumes.

That ties into n-level undo, because if you have no parent-child relationships, and you don't call BeginEdit, then n-level undo is entirely out of the picture when using CSLA.

But again, you should be very careful in weighing the cost-benefit before using a bastardized object model, because the increased complexity and maintenance costs are non-trivial!

Copyright (c) Marimer LLC