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?