Presentation Model Example

Implementation Notes

The Presentation Model pattern attempts to extract non-graphical presentation logic out of view classes and into model classes. The resulting presentation model classes are abstractions of the user interface and are decoupled from view components. Each view observes the corresponding presentation model object, allowing screen updates to occur in response to changes in the state of the model.

The key classes are as follows:

Take a look at the class diagram to see the relationships between the key objects.

Naming Conventions

In this example I have chosen to name the model objects after their User Interface counterparts. So the model for the album browser is called AlbumBrowser. Since the views are only projections of the model onto the screen, I've given them the name of their corresponding model objects appended with 'View'. So the view for the album browser is AlbumBrowserView. This reinforces the notion that the model is the driving force of the application, and the view has a subordinate role.

Dependency Injection

The dependency injection technique is used to hook-up the view classes with their corresponding presentation models. One nice side-effect of this is the ability to reset the view by injecting a new presentation model. This only works because presentation state has been extracted into the model.

Observer Pattern

The views use the observer pattern to detect and reflect changes in the model. This is achieved easily in Flex with MXML bindings.

Validation

In a presentation model application the validation logic belongs in the model class. I've often felt Flex Validators are a little cumbersome to use from ActionScript code, so I haven't used them in this example.

Graphical logic stays in the view

As mentioned in the blog entry, logic that is strongly related to graphics and rendering does remain in the views. In this example, the construction of the 'Abandon Changes' alert box is handled by the AlbumBrowserView. However, the displaying and hiding of this alert box is still driven by state changes in the model.

Model encapsulation

I've deviated a little from Martin Fowler's description, by allowing the view components to bind directly to value objects. In his example, Fowler copies information from the underlying data model into the presentation model for display by the view.

New VO methods

In the Autonomous View and Supervising Presenter patterns, the user's edited data is stored in the UI controls themselves, prior to clicking 'Apply'. In the Presentation Model, I've moved state out of the view and into the model and can no longer make use of UI controls for storing edited data. So I need some place to put this data while the user is making changes and I decided to use another instance of the Album value object for this. To support this, I created two new methods on the value object: clone() and equals().

Package Structure

Although this is a very simple example, I've attempted to arrange the packages in a manner that would be suitable for a larger application.

About the Demo

The demo application is based on Martin Fowler's album browser example. I've added some very basic input validation to the controls, and a warning pop-up when a user navigates to a new album without saving.

A fake delegate class is used for 'retrieving' the albums. I haven't attempted to model Flex's asynchronous remoting behaviour when loading the albums, so the delegate is too simplistic to be referred to as a mock or stub class.

A collection of value objects represents the list of albums.