« October 2007 | Main | February 2008 »
November 29, 2007
Presentation Patterns - Passive View
Like the Supervising Presenter, the Passive View pattern is a derivative of Model View Presenter (MVP). Martin Fowler split MVP into separate patterns to highlight two common approaches for realising MVP.
The Passive View pattern also has some similarities with Code Behind since both achieve a complete separation of ActionScript and MXML.
Key Features
- State is in the view
- Logic is in the Presenter
- Presenter observes the view
- Presenter updates the view
- Presenter ‘knows’ about the view
- View does not ‘know’ about the Presenter
The key features of Passive View are identical to those of Supervising Presenter. The difference between the two patterns is the degree to which logic is extracted from the view. Views in a Supervising Presenter application are allowed to 'observe' domain or value objects in order to display information, but views in a Passive View application are managed entirely by their presenter object.
The Supervising Presenter pattern lends itself to User Interface frameworks that have synchronisation features (eg. bindings in Flex), by allowing controls in the view to synchronise directly with underlying domain or value objects. The Passive View pattern prohibits this kind of behaviour in the view, so synchronisation between the view and the data model is managed by the presenter class instead.
Motivations
The motivations for the Passive View are similar to those of the Supervising Presenter and Presentation Model:
Easier to test
By moving all behaviour out of the view, the Passive View pattern is likely to afford the maximum unit test coverage of all the patterns I've looked at. The presenter class has a reference back to the view; so mock objects will be required to test it.
Improved Separation of Concerns
As with the other extract class refactorings, the Passive View pattern can help improve the separation of concerns in an application. By favouring composition over inheritance, Passive View achieves a greater degree of decoupling from the Flex framework than the Code Behind pattern. Presenter classes do not need to extend from Flex containers.
Language Segregation
By moving logic out of the view, the Passive View pattern can achieve similar developer / designer workflow objectives as Code Behind. The resulting view class is free from event handler specifications, binding statements and script blocks.
Issues
I think all of the issues identified for Supervising Presenter also apply to the Passive View. Rather than repeating myself, I'll just refer you back to that discussion.
Reduced role for MXML
As I suggested when discussing the Code Behind pattern, I don't believe MXML is just for designers. Although it is primarily targetted at describing the look of an application, it also offers features that support developers. Keeping MXML for designers means developers do not have access to MXML bindings and declarative event handler specifications. This isn't the end of the world and developers will adapt, but it does mean that some of Flex's more powerful features are no longer being used.
What about declarative behaviour?
Some presentation behaviour can be achieved declaratively in MXML; effects, transitions and validators are all examples. Whether Passive View permits this kind of declarative logic in the view isn't clear. It is probably safe to leave graphical behaviour in the view and drive state changes from the presenter if necessary. Non-graphical behaviour such as validation is probably best moved into the presenter class since it is likely to be more closely related to the underlying data model.
Example application
The example application demonstrates the Passive View pattern; right-click to access the source.
Final thoughts
The Passive View pattern goes a step further than Supervising Presenter by placing additional constraints on the autonomy of the view. But what interests me most about Passive View is the way in which it achieves similar goals to the Code Behind pattern through the use of composition rather than inheritance. For me this is a reminder that there is usually more than one way to solve a particular problem, and that the popular or mainsteam approach may not always be the best option.
Posted by paulw at 7:20 AM | Comments (2)
November 15, 2007
Presentation Patterns - Code Behind
Code Behind is a somewhat vague term that means different things to different people. I believe it was originally coined by Microsoft to describe any strategy for separating logic from content in ASP pages. Using this broad definition it could be argued that the Supervising Presenter, Presentation Model and even the View Helper are all examples of the technique. So this interpretation of code-behind lacks the sort of precision we require to discuss it as a pattern.
However, one of the most common methods for achieving code-behind in ASP and .NET uses inheritance: Presentation logic is extracted out of the view class, and into the view's superclass. The technique has been brought over to the Flex world and is arguably one of the most talked-about and advocated presentation patterns. It is this "code-behind pattern" that I am going to look at today.
Key features
- Logic (and other "developer" stuff) is in an ActionScript superclass
- Layout (and other "designer" stuff) is in an MXML subclass
Motivations
Language Segregation
I think the primary motivation for the Code Behind pattern is the segregation of ActionScript from MXML in order to support a developer/designer workflow. The precise division of responsibilities between ActionScript and MXML varies across implementations. Event handler specifications are usually extracted into the ActionScript class, but there seems to be some difference of opinion on whether binding statements can remain in MXML. It is also unclear whether designers can be expected to configure declarative validation in the MXML file. In my example I have extracted event handlers, binding statements and validation into the code-behind class.
Unit Testing
I've not seen much discussion of unit testing Code Behind classes, but I suspect they may be more 'testable' than equivalent Autonomous Views.
Code-behind classes contain references to sub-views; so unit testing them is likely to require mock objects. Since instances of sub-views are instantiated by the MXML subclass, it will be necessary to find a way to inject suitable mock instances when unit testing the base-class.
In addition to having references to sub-views, code-behind classes also contain references to UI controls. Since Flex controls do not implement interfaces, it is unclear to me how they could be mocked in the traditional sense. I think further investigation is required to understand the issues here.
Issues
Why extract superclass?
With the exception of the Autonomous View pattern, all of the patterns I've looked at so far attempt to extract logic from view classes into a separate set of ActionScript classes. This kind of refactoring is often referred to as 'extract class'. The Code Behind pattern is unique in that it attempts to extract logic into a superclass, a variety of refactoring known (somewhat unsurprisingly) as 'extract superclass'. Generally speaking the extract superclass refactoring is applied to move functionality shared by two classes into a base class in order to reduce code duplication. But in the case of Code Behind, we only have one view class. So why use extract superclass?
Poor separation of concerns
By performing an extract superclass refactoring, the resulting ActionScript class is still very likely to extend one of the Flex framework components such as HBox, VBox, or Panel. So it is difficult to see any real separation of concerns. As with the Autonomous View pattern, the layout concern is still central to the class hierarchy and code-behind classes are unlikely to have a common editable base class.
Tight coupling
The two classes resulting from the code behind pattern are very tightly coupled. An inheritance relationship is arguably the most intimate of associations. In advanced architectures it may be desirable to have more than one logic class for each view (for example to provide different view behaviour for different user roles); this isn't possible when the view extends the logic class.
Is MXML only for designers?
Perhaps I'm being selfish, but there are two very useful features of Flex that are only available in MXML:
- Bindings with curly braces '{}'
- Declarative event handlers
Whilst I could probably live without these two features, I'd prefer not to.
Example application
The example application demonstrates the Code Behind pattern; right-click to access the source.
Final thoughts
It isn't clear to me why the Code Behind pattern favours inheritance over composition, and I think this is the main drawback to the approach. Although logic is extracted out of the view, the resulting code-behind class is still tightly coupled to the Flex framework. Furthermore by having the view extend the code-behind class, the view becomes very tightly coupled to the logic.
By favouring composition over inheritance, the Supervising Presenter and Presentation Model patterns offer improved separation of concerns and consequently greater flexibility. Neither of these patterns achieves the same degree of separation between MXML and ActionScript as the Code Behind pattern, but the next pattern I'm going to look at certainly does. It's another one of Martin Fowler's and it's called Passive View.
Posted by paulw at 7:04 AM | Comments (9)
November 5, 2007
Presentation Patterns - View Helper
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.
Key features
- 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.
Motivations
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:
Mediation
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.
Language Segregation
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.
Decoupling
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.
Unit testing
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.
Issues
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.
Example application
The example application demonstrates the View Helper pattern; right-click to access the source.
Final thoughts
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
Posted by paulw at 9:32 AM | Comments (1)
