Discussing PureMVC or for a matter any micro-architecture is pointless without clear understanding of the Publish/Subscribe pattern. Why is that Publish/Subscribe is such a fundamental pattern?
The Publish/Subscribe Pattern
One of the first things a programmer should acquire about object oriented programming is the attitude not to care. Not to care about the internal workings of an object implementation, not to care about the unrelated details, relationships, component dependencies and underlying technology. Not carrying is not just about avoiding brain stress or being cool, but to put additional effort to achieve exactly 3 things:
1. Encapsulation or please, hide this dirty underwear.
2. Strong cohesion for doing one thing, but doing it right.
3. Loose coupling for being independent and not to need more to get more.
The PureMVC Micro-Architecture
On almost every Flex event organized by the Bulgarian Flex User-group there are guys asking about how to use Cairngorm or PureMVC. As I said before it’s perfectly normal for a beginner to seek for an architecture with which he can approach every new application in relatively uniform way. That’s why I’m writing about Cairngorm and PureMVC - both are pretty general approaches and the focus of this second part is the PureMVC micro-architecture.
As the name says this is an MVC micro-architecture. It’s comprised from Model, View and Controller - all these three are hidden under a Façade - a singleton delegating corresponding responsibilities to the Model, View and Controller singletons. These are the core actors.
The Model caches named references to Proxies, which expose an API for manipulating the data model (including data retrieved from remote services). The View primarily caches named references to Mediators, which adapt and steward the UI components that make up the user interface. The Controller maintains named mappings to Command classes, which are stateless, and only created when needed. The Façade initializes and caches the core actors (Model, View and Controller), and provides a single place to access all of their public methods. If you pay attention you’ll see 3 new concepts in the above description - Mediators, Proxies and Commands - well, almost new, because these are very similar respectively to the ViewHelpers, BusinessDelegates and Commands from Cairngorm, but they’re definitely not the same and the differences between them are worth noting. Mediators help us to create or reuse existing user interface components without the need to imbue them with knowledge about the PureMVC application they communicate with. The benefit of using Mediators is they can be positioned closer to the view compared to the Cairngorm ViewHelpers. Being closer Mediators can handle immediately user interaction events that are not significant for the whole application, but just for the sake of the UI components comprising the corresponding view. Just like ViewHelpers, Mediators can be retrieved from the View and used within Commands or other Mediators. To register or retrieve a Mediator, you should use the Façade. Another advantage is the ability to use immediately Proxies without the need to trigger execution of Commands - this is not the way Cairngorm works - BusinessDelegates are invoked only from within Commands. Proxies help us to expose data structures and entity classes (and the domain logic and services that support them) to our application in such a way that they may be easily reused elsewhere, or refactored with a minimum amount of impact to the rest of the application. Major thing to note is that we can use Proxies to simply manage a reference to a data object, and interact with this data object synchronously through the getData() and setData() methods. This seems to me messier than the approach used in Cairngorm. While in PureMVC you can use the Proxies for both synchronous and asynchronous interactions with data, Cairngorm makes clear separation between these two types of interaction - you can only interact synchronously with the data stored in the ModelLocator and every time you need to store or retrieve data from the back end, which is asynchronous operation you should use BusinessDelegates. Another point to ponder is that Cairngorm also advocates clear separation of services from the BusinessDelegates with the use of the ServiceLocator - a centralized storage for all the services the application consumes. PureMVC provides no such separation, but you can always try to organize your Proxies in a layered fashion where synchronous and asynchronous interactions are on different layers. I won’t say much about the Commands, because you’ll find them pretty analogous to the Cairngorm commands.
Conclusion
In conclusion I should say that you really need to read the documentation for the framework you’re planning to use, especially if you’re a beginner or have not enough experience to accept or reject such a reasonably looking micro-architectures like PureMVC and Cairngorm. Take PureMVC for example - if you read carefully the documentation you won’t omit the Goals&Benefits section, which clearly states the following under Goals:
This simply means that the PureMVC is avoiding the use of Flex, and it’s originally designed not to use Flex. So, where is PureMVC applicable? I should say, it’s applicable to the design and development of big Flash applications, but in cases of big Flash applications it’s always good to take some time to consider doing it with Flex.
Reference
PureMVC.org - the official site of the PureMVC framework
This post is tagged Adobe Flex, architecture, Cairngorm, flex, introduction, pattern, PureMVC




5 Comments
Hi,
One thing I’m trying to get my head around is how two different PureMVC applications could work together. The reason I’m asking is that I’ve decided to write a little debugging tool that I will comple to an SWC so I can use it in ongoing projects for simple debugging. I was going to write it using pureMVC as the framework. However I’m mainly developing my main applications using pureMVC now (this is because of the company I’m working for, if I had a choice I’d use Cairngorm) So am I right in thinking that this will not work as there can only be one Facade, Model and Controller so my little debugger could interact badly with other applications especially if I, or others in the team, inadvertantly use the same names for commands, variables in the model etc. Or can we have two pureMVC modules in the same app co-existing?
Thanks,
Tim
Hi, Tim,
First of all, thank you for this interesting question!
It looks to me, you’ve just confronted the classical dependency problem. How to make a Flex module that’s devoted on debugging other modules without leaving code dependencies in this debugging module? Let me rephrase to get clear enough - you want this debugging module to be ready for usage of the shelf, without the need to recompile it every time you need to debug a new module.
That’s one aspect of the problem - the other is about how to use two instances of the PureMVC micro-architecture? Well, that’s not that hard… Imagine two Flex modules - Debugger and TimApplication. Both modules are implemented with the use of PureMVC, thus both modules have instantiated a Façade. But this facades are different objects and objects can send each other messages - you need just to introduce the objects and let them get to know of each other existence. How to achieve that? Let me give an example in MXML:
<mvc:TimApplication id="timApplication"/> <debug:Debugger id="debugger" debugFacade="{ timApplication.facade }"/>We’ve just introduces TimApplication to the Debugger module and now the Debugger can send messages to TimApplication, messages like the following:
You can send all the messages that are in the IFacade interface. With this approach you’ve also achieved the general problem of removing the dependency between the two modules. How’s that?
1. The debugFacade-property should be of type IFacade and never of a concrete type, like TimApplicationFacade or SomeOtherApplicationFacade, but all the modules we want to debug should be implementing IFacade.
2. You use Inversion of Control (IoC). The configuration of the Debugger module is extracted outside the Debugger module.
<debug:Debugger id="debugger" debugFacade="{ timApplication.facade }"/>This declaration is outside the Debugger module and we configure the debugFacade property with the help of a pattern known as Setter Dependency Injection. The debugger module should look like:
public class Debugger { private var _debugFacade : IFacade; public function set debugFacade(value : IFacade) : void { _debugFacade = value; } public function registerDebugCommands() : void { _debugFacade.registerCommand(...); _debugFacade.registerCommand(...); } }Best Regards,
Vladimir
Tim,
Examine the MultiCore version of PureMVC. This not only solves your problem, but is easier to unit test since you can get a new MVCF ‘core’ for each test.
-=Cliff>
Incoming Links
Leave a Reply