Presentation Model Thoughts
I'm currently spending time on a user interface framework for the 2005 version ("Whidbey") of Windows Forms. Yesterday, I tried to implement a version of Martin Fowler's Presentation Model and incorporate it into my existing architecture. Part of my interest is based on the desire to remove as much user interface behavior from the view as possible. Since the Visual Studio visual designers encourage the blending of both view and controller behavior into the same class, introducing an abstraction like Presentation Model tends to "fight" what the IDE incents a developer to do.
Another goal of disconnecting the presentation from the behavior is to make it easier to write unit tests. I've been asked before about unit testing the user interface, and although I maintain that it's a worthwhile goal (since code is code is code), it proves to be difficult to automate without special tools. Introducing a pattern like Presentation Model should alleviate some of that pain. However, the challenge I'm facing is that implementation of a Presentation Model ends up requiring a lot of extra grunt work. Even Fowler admits that it is often repetitive code best suited for frameworks.
In my design, the business object manages its own state and defends itself from corruption by tracking rule violations (like "Name: Cannot be blank"). Without a Presentation Model in the picture, the view maintains a direct reference to the business object and subscribes to a Changed event to know when to update itself (à la typical Model-View-Controller semantics). Rule violations are indicated by displaying a textual summary and color-coding appropriate controls on the user interface.
While implementing the Presentation Model, it seemed like I was nearly re-implementing the entire state of the model and then some (to account for widget behavior in the UI). But, since I need the business object to defend itself against invalid data, it still needs to be involved in the process. In other words, updating just the state of the Presentation Model isn't good enough...I also need to update the actual business object so that it can validate its state and track rule violations.
Since I'd like to include "Apply" semantics in my framework, I don't want the controller/view to update the original business object, because that makes a Cancel operation more difficult to implement. I had hoped that a Presentation Model would hold modified values and only save them to the underlying business object when an Apply command is issued. To get around this problem, I can certainly Clone the business object and provide it as the model that gets modified. Then, when the user applies the changes, the original model would simply be replaced. Although this will work, care must be taken in case other areas of the system are maintaining active references to the older model (probably better to apply the state of the modified business object to the original to avoid this issue altogether). If the Presentation Model held the object state, Apply would simply copy the captured values to the underlying business object. And, of course, Cancel would do nothing at all.
In the end, I decided that although the Presentation Model pattern would make unit testing easier and it would make it nearly trivial to expose another user interface or view (as long as the view was relatively similar), for my purposes, it ends up being a little too academic and impractical. It would require too much maintenance, and I'm all for simplifying the architecture if at all possible. That doesn't mean that the pattern is bad; it just means that it isn't appropriate for my user interface framework.
Has anyone else tried to implement a Presentation Model?
Comments
- Anonymous
October 28, 2004
Hi Michael,
For a week ago I talked to Fowler about removing the synchronizer method to use a UI mapper instead to fill our domain objects, he thought that sounds like a good approached. The problem with the Presentation Model is that we have to write our synchronizer method for getting the user inputs and also setting the value of our controls. With a UI mapper we could easy map controls to any kind of object and specify the mapping in an XML file. By doing this we don't need to manually create the synchronizer method, instead we could use a UI mapper that will set the Presentation Model's property for us. - Anonymous
October 28, 2004
Thanks for the feedback, Fredrik. I like your idea of an XML mapping between the presentation and its associated behavior. However, I'm trying to leverage the Visual Studio 2005 IDE where possible (for the developer productivity benefits), and forcing a developer into an XML mapping file might be a little more than they would bargain for. On the other hand, it might be a good excuse to write a designer for Visual Studio that handles the dirty work visually. Now you have me thinking. :) - Anonymous
November 01, 2004
The business objects that I showed you when you visited (Rocky Lhotlka's CSLA framework) has all the rules in the business object but also implements multi-level undo. The initial state of the business object is serialized and persisted, while databinding handless changes to the "current" business object. If you want your UI to allow the user to set "bookmark" point, the framework serializes the object again allowiing the user to save changes, undo to the bookmark or undo to the initial state of the business object. - Anonymous
November 01, 2004
Ray...Sounds like an implementation of the Memento design pattern, which works well in Undo/Redo situations.