The next pattern I want to look at goes a step further than the Supervising Presenter by moving logic and state out of the view. Once again discussed by Martin Fowler, the Presentation Model has its roots in the Model-View-Controller (MVC) pattern.
A presentation model is an ‘abstraction’ of a view. In other words, the model represents the behaviour and state of a view, without getting involved with any of that messy graphical stuff. The view represents a projection or rendering of the model onto the screen. When changes occur in the presentation model, the view updates itself on-screen.
Martin Fowler describes two variants of the Presentation Model, one in which the view observes the model, and another in which the model observes the view. I will be looking at the former in this discussion because in Flex it is far easier to set-up observer relationships from MXML views to ActionScript models.
- State is in the presentation model
- Logic is in the presentation model
- View observes the model and updates accordingly
- The view “knows” about the presentation model
- The presentation model does not “know” about the view
Model-view synchronization is usually achieved by applying the observer pattern, and in Flex this can be realised with MXML bindings. Although the view ‘knows’ about the underlying model, the model is unaware of the view; compare this with the Supervising Presenter, where the opposite applies.
Furthermore, in a Presentation Model application, view state and logic are both extracted from the view into the model. Again this is in contrast to the Supervising Presenter, in which only logic is moved out of the view; and the Autonomous View, in which logic and state remain in the view.
As with the Supervising Presenter, the motivation behind the Presentation Model is to address issues with the Autonomous View approach:
Since Presentation Model classes are fully decoupled from the view, the logic they contain is much easier to test. This puts the Presentation Model ahead of the Supervising Presenter, since the latter has a reference back to the view. Writing FlexUnit tests for presentation models should be no more difficult than for other kinds of model classes.
Improved separation of concerns
If each presentation model represents an abstraction of a view, then together they can be thought of as a model for an entire user interface. Common presentation behaviour can be refactored into base classes and shared throughout the model. I can see enormous potential here, which I hope to explore in the future.
How much logic and state should be extracted?
As much as possible. Most non-graphical presentation concerns are candidates for extraction into the model. Presentation concerns that have a strong graphical component (such as animation) and concerns that are closely coupled to the underlying framework (such as drag-and-drop) may be best left in the view. Coding this logic into the model would require too much knowledge of screen size, layout and the kinds of UI widgets being used.
Some logic is likely to remain in the view
As mentioned above, logic that is directly coupled to graphical concerns will need to stay in the view. The Supervising Presenter does not have this restriction, because it is allowed to ‘know’ about the view.
The view also needs to be ‘smart’ enough to know which methods to call on the presentation model in response to input events.
The example application demonstrates the Presentation Model pattern; right-click to access the source.
Both the Supervising Presenter and Presentation Model allow you to create a separate class hierarchy for your application-specific behaviour. The former uses the view to store UI state, the latter places the state in the same class as the logic. By being decoupled from the view, the Presentation Model pattern offers more convenient unit testing and improved decoupling from the view. However, the model’s total ignorance of the view means that some of the more ‘graphical’ behaviour cannot be extracted.
Up next: View Helper