While in part 2 I had discussed the role of the Mediator in the PureMVC framework, Jesse Warden wrote a very intimate article about his experience with Cairngorm and PureMVC - No Mediator vs. No Singleton in Cairngorm & PureMVC - thus reminding me that I need to emphasize more on the important role of the Mediator.
More on the Mediator
In my previous article I was describing the need to have an agent near the View in order to handle complex user interaction instead of running the whole cycle of processing Cairngorm events, but most importantly to make possible View reuse. To make something reusable it should be abstract as possible - this means not only removing any business specific logic from the View-component, but also to reduce the necessity to imbue other application components with certain knowledge about this View-component. The lesser they need to know about it, the better. So far, so good, but I’ve omitted and missed entirely to write about Mediators as translators. Removing business specific logic from the View-components, means that the View-specific events should be mapped to business logic events. As you might guess the Mediator is the dude performing this so important mapping - it intercepts the View specific events and then dispatches the corresponding business specific events that usually trigger Command execution.
The bitch in Cairngorm is the lack of a Mediator. Novices do dispatch Cairngorm events directly from the View-components, thus making these components not very reusable - sometimes you might be able to reuse them in other Cairngorm applications, but you have to be careful not to duplicate an already existing Cairngorm event. In the above mentioned article Jesse Warden suggested that Cairngorm needs a formalized concept for a Mediator, just as in PureMVC. I agree on that, but later in this article I will describe an approach bit more natural to Flex.
The Gugga Approach
In the rest of the article I’ll write about the approach we use in the company I work for - it is not something new - I’ll write about things that have been around in the Flex community for a while and have been used successfully by plethora of Flex practitioners.
In part 1 and part 2 I’ve been showing you couple of architectures you can use almost right away as skeletons for your applications, but those architectures are way to MACRO to deal with the real challenges in building RIAs - user experience, human computer interaction and custom UI components - these are impossible to deal with using a MACRO approach. Sure, application architectures are important, but as soon as you gain the experience, you’ll start designing your own custom tailored application specific architectures, just like the sample architecture on the simple diagram below:

On the diagram I’m showing couple of Flex modules or just Flex components, which are implementing the MVC or MVCS (Model View Controller Service) patterns, but not in the terms of PureMVC or Cairngorm - I’ll get into more detail in the next section. The Application Controller manages the life-cycle of these modules and it is also responsible for catching application specific events from the modules, injecting the needed data for the modules, controlling the transitions between modules and updating the business specific data, which is kept in synch with the help of a Data Manager. This is a rather MACRO MVC architecture - where the Model is comprised by data and a Data Manager, the View is composed by modules, and the Controller is the thick thing in the middle.
An Architectural Blueprint for Flex Applications
Almost two years ago Joe Berkovitz wrote an article for the Adobe DevNet which to my opinion had a deep influence not only on a MACRO-level as a prescription for Flex application architectures, but also on a more MICRO-level as a blueprint for engineering Flex modules and Flex components. The realization that this MVCS approach is applicable in making Flex components didn’t came at once - it took us almost a year of building custom Flex components to discover the bitter truth that Flex framework UI components are not designed in the best way to cope with the broad spectrum of customization requirements. The current design and implementation bundles the core functionality of a component with an almost hard-coded view, thus forming a complex monolithic component. So instead of having a flexible way of customizing the view and the behavior through smart usage of inversion of control and dependency injection, right now the developer is constrained with overriding existing functionality and very often the sole possible way of getting the job done is to copy and modify code from the Flex framework. Off course the new versions of the Flex framework will introduce more and more improvements - the changes for the next version wouldn’t be that drastic as I want, but still they will address the most painful problems.
Instead of summarizing the blueprint proposed by Joe Berkovitz, I’ll show you a real MVCS-implementation, but before that you need to know what is inversion of control and how to use dependency injection in Flex.Inversion of Control (IoC) Patterns
IoC patterns have two major goals - reducing class dependencies and extracting the creational logic and the components dependencies management outside the component. Let’s take for example this short code fragment:
package com.sample
{
public class Loader
{
public function load() : void
{
...
var bar : IBar = new LoopingProgressBar();
...
}
}
}
This piece of code looks all right to the point when we decide to change the looping progress bar with a download progress bar. First the Loader has no core functionality changes what so ever, but because of this small change of the progress bar, we’ll end up messing with the Loader’s code and eventually it will need another compilation. Another way of doing this is to decouple the creational logic and use dependency injection as a form of runtime configuration of the Loader.
package com.sample
{
public class Loader
{
private var _bar : IBar;
public function set bar(value : IBar) : void
{
_bar = value;
}
public function get bar() : IBar
{
return _bar;
}
public function load() : void
{
...
// using the injected IBar-reference
...
}
}
}
In the code above I’m using the so called setter dependency injection, thus someone outside the Loader component will need to care about creating and injecting the proper progress bar instance, instead of hard-coding it inside the component. To be able to do that we need to use interfaces (or the most abstract form available) instead of concrete classes - this is how we avoid class dependencies.
MVCS with Inversion of Control
The way we do IoC in Flex is related to the Flex UI component life-cycle and the way in which the Flex data binding is triggered. We use these mechanisms instead of having a sophisticated IoC-containers, which is great because you don’t need to learn any new API. Actually you don’t really need to learn anything new if you’re already familiar with data binding and the Flex UI component life-cycle.
Let’s take a look at a typical MICRO-MVCS:
<gallery:PhotoGalleryClass xmlns:gallery="com.sample.gallery.*">
<gallery:Model id="model"/>
<gallery:Controller id="controller" model="{model}" service="{service}"/>
<gallery:View id="view" model="{model}"
nextPhoto="controller.loadNextPhoto();"
prevPhoto="controller.loadPrevPhoto();"/>
<gallery:Service id="service"/>
</gallery:PhotoGalleryClass>
This is the PhotoGallery.mxml component which inherits the PhotoGalleryClass as a form of a “code behind”. This component consists of a Model, a Service, a Controller that is injected with the Model and Service instances, and a View which is data bound to the Model. The nextPhoto and prevPhoto-events dispatched from the View are handled by invoking the Controller methods loadNextPhoto() or loadPrevPhoto() - these methods are using the Service to obtain from a remote destination the next or the previous photo in the gallery and to update the Model with the newly received data. The data binding between the View and the Model will automatically trigger the View updates.
Simple, huh? And all parts of this composition are potentially reusable. This type of micro-MVC is getting more and more popular. The OpenFlux component framework is using a very similar architecture for every component in the framework, so it’s pretty convincing that this simple MVC combined with the power of IoC can be applied on different level of granularity, like for example the PhotoGallery.mxml can be a whole module or a whole application, or much simpler custom component. Ben Stucki wrote a very nice introduction to OpenFlux and I recommend you reading it. It is a very brief introduction, so it will take you less than 5 minutes to learn some very powerful concepts. You’ll notice that in OpenFlux there is no formalized Model, but if you think about it in most of the cases a change in the Model is very often coupled with a change in the component functionality, so this probably led to the decision to use the component itself as the Model for OpenFlux components.Conclusion
Both Cairngorm and PureMVC originate from technologies which are not Flex, but Flex has some very powerful features like declarative style of programming inside the MXML and Data Binding. These combined with the UIComponent life-cycle gives us the functionality of something like an IoC-container. Getting more experienced with Flex will help us find much simpler and more powerful ways of using this IoC capabilities, which eventually will lead to designing application architectures more natural to Flex.
Reference
An Architectural Blueprint for Flex Applications by Joe Berkovitz
An Introduction to OpenFlux by Ben Stucki
OpenFlux is an open-source component framework for Flex which makes radically custom component development fast and easy.
This post is tagged Adobe Flex, architecture, flex, introduction, mvc, mvcs, OpenFlux




4 Comments
Do you have a code zip with the full PhotoGallery example?
thx,
ADG
No, I don’t have it, cause it’s just a fast written sample to illustrate the concept. But, it’s so unfortunate to let you get out of my blog empty handed, so if you really wanna touch this concept, you can check out Obecto’s corporate site and see the code of the application, shared on Google Code.
If I want to show the most complicated scenario of using this type of IoC MVC, I would use a sample that shows a Flex module structured in this way. The module is the best scenario, because you may need to inject some application-wide things, like common services, common model, etc.
Please, let me know if you have further questions!
Very interesting series of articles. thanks.
Incoming Links
Leave a Reply