While looking at the Supervising Presenter and Presentation Model patterns it occurred to me that some people may find these concepts reminiscent of the View Helper pattern that enjoyed a spell of popularity in some Cairngorm architectures. Since the View Helper is now regarded as ‘not recommended’, I want to take a closer look at the pattern and try to understand why it may have fallen from favour.
The View Helper is loosely based on a similarly named J2EE pattern, but the purpose and realisation of the pattern within Flex applications is somewhat different to its server-side counterpart.
- State is (mainly) in the view
- Logic is (mainly) in the view helper
- The view ‘knows’ about the view helper
- The view helper ‘knows’ about the view
As with Supervising Presenter and Presentation Model, the View Helper pattern extracts logic from view components into ActionScript classes.
Tracking down the original motivations for the View Helper pattern is more an exercise in historical research than technical investigation, but here are a few possibilities:
Steven tells me the View Helper has its roots in RIA development using Flash. It was introduced to act as a mediator for views in an application. Back in those days, views were constructed as a hierarchy of movie clips. For these movie clips to find each other and collaborate directly they would need to know quite a lot about the structure of the view. Rather than duplicating this ‘knowledge’ around the view hierarchy, it was encapsulated within the view helper class. So when the structure of the view changed, only the view helper needed to be updated.
The problem the View Helper pattern addresses in Flash is less of a problem in Flex, because of the "flattening" effect composite view components have on the view hierarchy. But the mediator pattern is certainly relevant to Flex applications: both the View Helper and Supervising Presenter patterns perform mediation between UI components.
Another justification for the View Helper pattern is to achieve a segregation of MXML and ActionScript. For some, this is to enhance readability or tidyness of the code, and for others it is to support some kind of designer / developer workflow.
In the days before the miracle of Flex bindings and the omniscient ModelLocator, it was necessary for Cairngorm commands to directly update views with the results of remote operations. In order to avoid coupling the commands to the views, the View Helper was used as an intermediary. The View Locator pattern was also employed to allow the view helpers to be ‘located’ by the commands.
As we’ve seen with two of our previous patterns (Supervising Presenter and Presentation Model), one objective is improved ‘testability’. From the perspective of the view helper, the reference back to the view will cause the same unit testing difficulties as apply to the Supervising Presenter. Dependencies in this direction could be loosened by having the view implement an interface, and coupling the view helper to the interface instead of the concrete view class. This would allow testing of the view helper with mock objects.
Libraries instead of classes
View Helpers are usually little more than ActionScript libraries for their corresponding views. In most cases they don’t form their own structure of collaborating classes or exist within a broader class hierarchy, and they cannot be really described as an architectural layer. Each one is just a file in which to hide away the logic for a particular view.
View helpers are lonely
If you take a look at the class diagram for the demo application, you may notice there are no direct associations between view helpers. So although the logic has been extracted from the view into a separate class, this new class must still rely on the view in order to collaborate with other classes. The lack of associations between view helpers severely limits their value as a means to separate concerns. This caused me some problems when coding the example, and I found myself with awkward statements like:
view.form.helper.album = album;
One way to avoid this issue would be to move some of the ’setter’ logic back into the view. Another approach would be to introduce a singleton that would allow view helpers to be ‘located’ by other view helpers. Neither option is particularly satisfactory.
View creates the helper
Should the view be creating the helper? Giving this responsibility to the view reinforces the notion that the view is still in charge, and the helper is a subordinate. I tried to avoid this for the Supervising Presenter and Presentation Model patterns, favouring injection instead.
The example application demonstrates the View Helper pattern; right-click to access the source.
The View Helper pattern isn’t a great distance from either of the Supervising Presenter or the Presentation Model patterns discussed previously. But it doesn’t seem to achieve the same benefits, and this may be because the motivations for the pattern have been forgotten or have gradually lost their relevance. As a mediator, the View Helper does not achieve the same separation of concerns as the Supervising Presenter: there is a bi-directional coupling between the view and the helper, and the helper must rely on the view in order to find and collaborate with other view helpers. By improving testability, the View Helper could be regarded as a step in the right direction, but as a refactoring it just didn’t quite go far enough.
Next up: Code Behind