More than one year ago we started to deeply study the Model View Presenter pattern because we found that there lot of good point to improve the architecture of our Flex application.
The aim of this post is to share our experience (bottom up approach) and the way we are used to define the building blocks of our architectures and try to start creating a little bit of culture of architectures in the Flex world.
We are not working on a new ActionScript framework, the word framework for us means something like Spring or Tapestry or Flex, we are only delivering as open source a class set we build over the last 14 months with some suggestions and sample about how to use the Model View Presenter as an organizational pattern to follow in complex Flex / Air applications.
The first thing that attracted us in the MVP pattern is that the presenter knows its associated view only trough the interface the view implement. This interface represents the way the presenter get information from the user interface and the way the view is updated by the presenter in order to show the data is working on.
A web or a desktop application is a matter of data manipulation and visualization, enforcing the separation between these two fields you are able to split data, presentation, and user input into specialized components self independent, pluggable and loosely coupled so that you can get the following benefits:
• Development of component can proceed simultaneously
• Each component have a common architecture
• Developers can work on each component of an application (shared architecture)
• Dependencies in the application are under control
We are used to put in place for each component a folder structure like this one
so that you have inside the view folder the MXML file that represents the GUI of your component on which, trough an interface, the presenter work on (i.e. get data and display data) and the folders in which you can store formatters and helpers.
The helpers are classes that can help your view to render data correctly, for instance if you need a filter function for a data grid in the view it’s better to have stored in an helper rather then put some complex scripts inside the view.
We follow the same logic for the formatting, if you are not using the standard formatters provided with the Flex framework the formatters classes can be stored in a separate folder so that you keep clean and easy to understand the view.
In the presenter folder we are used to put the big boss (i.e. the presenter) and its helpers, this is the core of each component because it contains the logic and the handlers of the user inputs (i.e. typing, mouse click, etc.).
The model folder is something that we don’t see as mandatory in each component, the model is defined at an application level or at a library level, we use the model folder only if a component has some specific needs such as value objects, identities, aggregate roots, enumerations or services that are related only to this specific component.
These are some points to keep in mind when dealing with model view presenter
• Is the presenter that handle user input and data manipulation
• While it is the view’s responsibility to display model data it is the presenter that governs how the model can be manipulated and changed by the user interface
• This is where the heart of an application’s behavior resides
• In many ways, a MVP presenter is equivalent to the application model in MVC
• Most of the code dealing with how a user interface works is built into a presenter class
The main elements of our mvp architecture are
The Mapper class is the one that stores a dynamic list of UI elements that have to interact between each other, it contains a reference to the instructions it has to deliver, it is created in the application initialization and It’s able to get and dispatch events.
The Presenter class is the base class of each presenter, it requires an IView implementor (simply an empty interface that extends the IEventDispatcher) and the property on the model you want to watch as arguments in the contructor in order to be used in a service oriented application (the onServiceFault, onResult and onUpdateFault methods have to be overridden in order to handle the result).
Keep in mind that the _dataSet property contains the data the view is working on and that is a good practice play on this data through a strongly typed getter and setter.
The IMapperCandidate is an empty interface to help the application to add the UI element to the Mapper, this interface has to be implemented if the component presenter needs to be in touch with other components trough the instructions.
The instructions are represented through an Event subclass, it ss used to send notifications between components added to the Mapper, each Instruction is fired trough a specific subclass of the InstructionEvent class (the reason why you have to create a subclass is in order to allow the Mapper to dynamically create the Instruction trough reflection).
In order to get more samples and information about the MVP implementation we did you can browse our wiki http://agile.gnstudio.com/nabiro, in the next weeks other posts about our flex / air applications will be posted on this blog.