Several months ago, I was looking for a framework that would streamline AS3 application development. Cairngorm and PureMVC were the most mature frameworks out there and I remember being particularly impressed with PureMVC mainly due to the solid documentation that came with it. Cairngorm may be robust, but I just couldn’t get my head wrapped around it by glancing at the docs and examples. In contrast, PureMVC came with a Conceptual Diagram that explained the framework using the design patterns that I was familiar with. Cairngorm does have similar diagrams that explain its microarchitecture, but it exemplifies my initial thoughts — I just couldn’t get a quick, big picture understanding of it easily. Not only has Cliff Hall done a masterful job on the PureMVC framework, but the effort he’s put into the documentation really underscores the importance of documentation and diagrams on dissemination and adoption.
Cairngorm or PureMVC?
Recently, Ali Mills and Luke Bayes made a presentation on Flex Application Frameworks. Their choices essentially boiled down to Cairngorm and PureMVC and concluded that PureMVC came out on top. However, I highly recommend that developers watch the whole presentation as many enterprise developers in the audience made comments that challenged the easy differentiation of the two frameworks. Having the backing of a stable organization like Adobe, as is the case with Cairngorm, means a lot for enterprise development. Also, this post on Bill Lane’s blog and several comments implying that PureMVC is much harder to learn than Cairngorm got me thinking if a really simple application would help scaffold the transition to PureMVC.
I’ve implemented the minimalist example from the MVC chapter of our book (available as a free download from Adobe Devnet) using the PureMVC framework. Now this is not a full-fledged application, but a very minimal example meant to explain the inner workings of the PureMVC framework. Before diving in, a brief introduction to some of the important aspects of the framework will help. This was the hard stuff that I had to internalize before starting out. These concepts are more eloquently explained in much greater detail by Cliff Hall in the framework documentation.
“You can’t touch this” - models, views and controllers that is
Although PureMVC is built on the traditional Model-View-Controller meta-pattern, you cannot create or directly manipulate these entities. The Model, View and Controller are already implemented in PureMVC as singletons and are essentially hidden. You do not develop Model, View and Controller classes but implement proxy, mediator, and command classes that broker the communication in your application. The PureMVC Conceptual Diagram shows this visually.
“Collaboration pairs” are better than singles
Cliff introduces the concept of “collaboration pairs”. In the traditional MVC pattern, the Model contains the data and business logic; the View presents the user interface components; and the Controller handles the user input and manipulates the model. However, since the model, view and controller classes are not directly accessible in PureMVC, they form collaboration pairs with other design patterns to provide more abstraction and loose-coupling than the traditional MVC pattern.
The Model - Proxy collaboration pair provides a means to access and manipulate application data. You develop and register a concrete proxy class with the model to provide controlled access to a data object. For example, a proxy can load data files from disk, or provide access to a remote database or web service. The proxy pattern provides an interface to the core application that hides the implementation details of accessing and manipulating data and application state.
The View - Mediator collaboration pair provides the means by which the user interface elements are presented and updated. You develop concrete Mediator classes that register with the View to provide the interface by which the core application communicates with the UI components. A single mediator class can have multiple UI components. For example. a login screen will have one mediator class but can contain username and password fields, and a submit button. The mediator pattern can hide the complex interactions between related UI elements from the core application.
The Command - Controller collaboration pair represents the means by which UI elements can manipulate the model. In a traditional MVC app, the Controller acts as a concrete strategy in a strategy pattern. In this sense, controllers are specific implementations that determine how the application responds to user input. For example, controllers can do validation checks on user input and decide if application data needs to be updated (through a proxy). In PureMVC, the strategy code is encapsulated inside Command Objects. This essentially hides the proxy class and proxy methods that are called to manipulate data objects from the mediator, reducing the coupling between the mediator and the proxy.
Again. the PureMVC Conceptual Diagram does a really nice job of showing the “collaboration pairs.”
Think in Notifications before Events
The mediators, proxies and commands talk to each other using a unique message passing scheme called Notifications. Notifications are essentially triggers that can carry data. Commands are bound to specific notifications. Only mediators listen for notifications. So, a proxy or command can send a notification that will trigger a Mediator to update a UI component. Proxies can send, but do not listen to notifications. A mediator can manipulate application data by sending a notification that will trigger a command to update a data object through a proxy. This shrewd design decision to develop a custom notification scheme has allowd Cliff to port the PureMVC framework to AS2, C#, Java, PHP, and ColdFusion.
The Events in Flash and Flex are not discarded, but used at the boundary of the application. Mediators can register and listen for events from UI components such as buttons and fields. Proxies register and listen for events when dealing with data objects such as when loading an XML data file asynchronously.
The Facade is your friend
You must create a concrete Facade class that makes the whole framework easier to use. The Facade provides a single class that unifies all the methods required to make PureMVC work. In addition, instantiating a facade initializes the PureMVC framework by creating the model, view and controller singletons.
These were the four big concepts that I needed to understand before diving into creating a PureMVC application.
The Minimalist Example
The example was developed using Flash CS3 and basically listens for user key presses, stores the last key pressed, and displays the key (MVC_minimalist_v1.zip). The example app was written in PureMVC Release 1.6. The package structure will change in release 2.0 and the import statements will need to be changed accordingly.
Make sure to download and install the PureMVC framework and make it accessible in your classpath first. The package hierarchy as shown in the Flash Project Panel is shown here for reference.

Here is a conceptual diagram that shows the classes and the notification messages. To start the application, call the startup() method in the the Concrete Facade class called ApplicationFacade. The numbers show the sequence of actions that take place.

- The Concrete Facade class called ApplicationFacade broadcasts a STARTUP Notification.
- The STARTUP Notification triggers the
StartupCommandcommand object which registers theKeyDataProxyproxy, andStageMediatormediator. StageMediatormediator registers a KEY_DOWN Event handler to the stage to intercept key presses. It also registers to receive KEYUPDATE Notifications.- User presses a key generating a KEY_DOWN Event that is intercepted by the key down event handler in the
StageMediator. StageMediatorbroadcasts a KEYDOWN Notification with the character code of the key in the notification body.- The KEYDOWN Notification triggers the
StoreKeyCommandcommand object, which accesses theKeyDataProxyproxy and updates the model (data object). - The
KeyDataProxyproxy stores the data in a data object (just a property in the proxy in this case). - The
KeyDataProxyproxy broadcasts a KEYUPDATE Notification with the character code of the key in the notification body. - The KEYUPDATE Notification handler in
StageMediatorintercepts the KEYUPDATE Notification and traces the key value.
The StageMediator mediator could have directly updated the model in step 5 through the KeyDataProxy proxy, without going through a command object. However, this introduces a tighter coupling between the Mediator and Proxy that should best be avoided.
The Concrete Facade
The first step is to create a concrete Facade class called ApplicationFacade to declare notification names and bind them to command objects.
The ApplicationFacade class defines the STARTUP, KEYDOWN and KEYUPDATE notification name constants. STARTUP and KEYDOWN are bound to the StartupCommand and StoreKeyCommand comand objects. In contrast, the KEYUPDATE notification is not bound to a command object. It is broadcast by the proxy to mediators informing them that the model has been updated.
The Facade is the entry point into the application and defines the startup() method that broadcasts a STARTUP Notification to the rest of the application. The startup() method has to be called from the document class of your Flash document (see Document Class below). Typically, the argument passed to the startup method should be the stage instance.
ApplicationFacade.as
package { import org.puremvc.interfaces.IFacade; import org.puremvc.patterns.facade.Facade; import org.puremvc.patterns.observer.Notification; import controller.*; public class ApplicationFacade extends Facade implements IFacade { // Notification name constants public static const STARTUP:String = "startup"; public static const KEYDOWN:String = "key down"; public static const KEYUPDATE:String = "key update"; // Singleton ApplicationFacade Factory Method public static function getInstance(): ApplicationFacade { if (instance == null) { instance = new ApplicationFacade( ); } return instance as ApplicationFacade; } // Broadcast the STARTUP Notification public function startup(app:Object):void { notifyObservers(new Notification(STARTUP, app)); } // Register Commands with the Controller override protected function initializeController():void { super.initializeController(); registerCommand(STARTUP, StartupCommand); registerCommand(KEYDOWN, StoreKeyCommand); } } }
The KEYDOWN notification is sent by the StageMediator Mediator (see below) when a user presses a key. The KEYUPDATE notification is sent by the KeyDataProxy Proxy (see below) to all mediators informing them that the model has changed.
The Commands
There are two command objects StartupCommand and StoreKeyCommand.
StartupCommand.as
package controller { import flash.display.Stage; import org.puremvc.interfaces.ICommand; import org.puremvc.interfaces.INotification; import org.puremvc.patterns.command.SimpleCommand; import view.*; import model.*; public class StartupCommand extends SimpleCommand implements ICommand { // Register the Proxies and Mediators override public function execute(note:INotification):void { // Create and register proxy facade.registerProxy(new KeyDataProxy()); // Create and register StageMediator with the stage instance as an argument var stage:Stage = note.getBody() as Stage; facade.registerMediator(new StageMediator(stage)); } } }
When the StartupCommand command object is triggered by the STARTUP notification it first registers the proxy called KeyDataProxy. It then registers the StageMediator Mediator and passes the stage to it. This is an essential practice in Flash applications as the Mediators require access to the stage to add UI components to it. Note that the StartupCommand command object expects the STARTUP notification to contain a reference to the stage in the notification body.
StoreKeyCommand.as
package controller { import flash.display.Stage; import org.puremvc.interfaces.ICommand; import org.puremvc.interfaces.INotification; import org.puremvc.patterns.command.SimpleCommand; import model.*; public class StoreKeyCommand extends SimpleCommand implements ICommand { override public function execute(note:INotification):void { // Get the KeyDataProxy proxy var keyDataProxy:KeyDataProxy = facade.retrieveProxy(KeyDataProxy.NAME) as KeyDataProxy; // Set the char code of the key pressed in KeyDataProxy var charCode:uint = note.getBody() as uint; keyDataProxy.key = charCode; } } }
The StoreKeyCommand comand object is triggered by the KEYDOWN notification that is sent by the StageMediator Mediator (see below). The KEYDOWN notification contains the character code of the pressed key in the message body. The command code retrieves the KeyDataProxy using the retrieveProxy() method and stores the character code using a setter method.
The Mediator
The example application just has one Mediator class called StageMediator that mediates interactions with the stage. It registers a Key Down even handler called onKeyDownEvent() with the stage. It also registers to receive KEYUPDATE notifications by overriding the listNotificationInterests() method. It also overrides the handleNotification() method to intercept and act on KEYUPDATE notifications.
StageMediator.as
package view { import flash.events.KeyboardEvent; import flash.display.Stage; import org.puremvc.interfaces.IMediator; import org.puremvc.interfaces.INotification; import org.puremvc.patterns.mediator.Mediator; // Mediator for interacting with the Stage. public class StageMediator extends Mediator implements IMediator { // Cannonical name of the Mediator public static const NAME:String = 'StageMediator'; // Constructor public function StageMediator(viewComponent:Stage) { // pass the viewComponent to the superclass super(viewComponent); // Listen for events from the view component viewComponent.addEventListener(KeyboardEvent.KEY_DOWN, onKeyDownEvent); } // Key down event handler private function onKeyDownEvent(event:KeyboardEvent):void { sendNotification(ApplicationFacade.KEYDOWN, event.charCode); } // Return list of Nofitication names that Mediator is interested in override public function listNotificationInterests():Array { return [ApplicationFacade.KEYUPDATE]; } // Handle all notifications this Mediator is interested in override public function handleNotification(note:INotification):void { switch (note.getName()) { case ApplicationFacade.KEYUPDATE: var charCode:uint = note.getBody() as uint; trace(charCode); break; } } // Get the Mediator name override public function getMediatorName():String { return NAME; } } }
The StageMediator mediator broadcasts a KEYDOWN Notification when it receives a KEY_DOWN even from the Flash event model. The character code of the key pressed is sent in the body of the Notification. On receipt of a KEYUPDATE Notification, the StageMediator simply traces it to the output panel (to keep things simple). It could have updated a UI element (e.g. Text Field) to show a change.
The Proxy
The minimalist example has one proxy called KeyDataProxy keeps track of the last key pressed by the user. The character code of the key is stored in the lastKeyPressed property in the proxy itself. The proxy could just have easily stored this value in an external data file or remote database if needed.
KeyDataProxy.as
package model { import org.puremvc.interfaces.IProxy; import org.puremvc.patterns.proxy.Proxy; public class KeyDataProxy extends Proxy implements IProxy { // Cannonical name of the Proxy public static const NAME:String = 'KeyDataProxy'; private var lastKeyPressed:uint = undefined; // Constructor public function KeyDataProxy() { super(NAME); // pass the cannonical name to the superclass } public function set key(charCode:uint):void { if (lastKeyPressed != charCode) { lastKeyPressed = charCode; // Create and send a KEYUPDATE Notification and pass the charCode as an argument sendNotification(ApplicationFacade.KEYUPDATE, charCode); } } } }
Note that the model stores the new character code only if it is different from the one already stored. It also doesn’t broadcast a KEYUPDATE Notification unless this is the case. This is why we needed two Notification messages, one to broadcast that a key has been pressed (KEYDOWN) and another to inform all interested mediators that the model has been updated with a new character code (KEYUPDATE).
The Document Class
The document class of the Flash document initializes the concrete facade and broadcasts the STARTUP notification.
Main.as
package { import flash.display.MovieClip; /** * Main Class * @ purpose: Document class for movie */ public class Main extends MovieClip { public function Main() { // Instantiate the ApplicationFacade var facade:ApplicationFacade = ApplicationFacade.getInstance(); // Call the application startup method and pass the stage as the argument facade.startup(this.stage); } } }
So, there you have it, a minimalist example in PureMVC implemented in the Flash CS3 environment. Make sure you Disable keyboard shortcuts from the Control menu when testing the application. The source can be downloaded below.
MVC_minimalist_v1.zip.
I’ll follow this up with another post extending the minimalist application a little bit (e.g. adding more UI elements and mediators) to demonstrate the value of the design decisions that went into PureMVC. This post is quite long and I’m sure there are some errors - comments and corrections are welcome.

Great informative post. thanks!
A great introduction to PureMVC. Much appreciated!
I’ve refactored the startup procedure on a recommendation by Cliff Hall as discussed here: http://forums.puremvc.org/index.php?topic=85.0
Now you don’t have to build a Notification in the document class, making it much leaner.
Thanks Tink and Neal - I’m glad this is helpful.
Great post! Anything to get the word out on PureMVC is good. I’ve used it for my last five projects, that include a sophisticated Flex app, two Flash-based children’s games, a sound-mixer, and a code-generator.
What I can say is, this framework is extremely flexible and great to use for just about anything. Thus far, it is my favorite and I plan to keep using it.
I’d really like to see those ports to other languages, as some of my non-Flash peeps are interested. The link above didn’t seem to work though…any update?
-t.
Hi Tim, thanks for pointing out the bad link to Cliff’s blog post about the ports (now fixed).
http://puremvc.org/content/view/44/41/
Sounds like the ports will be available soon.
I enjoyed your Design Patterns book Chandima, which lead me indrectly to PureMVC and then back here … I’m still struggling with some concepts and hoped you might be able to help me translate your MVC Car example to PureMVC. Just a quick package heirachy listing would save me some brain-pain and help me bridge the gap with Cliff’s HelloFlash sprite model. Specifically would you define the CarModel as a Proxy, or as a Mediator component? Thanks.
Hi Rob, glad you are working through some examples (I’m doing the same). The short answer is the CarModel should be implemented within a proxy. Generally, the model, view and controller classes in a traditional MVC pattern can be implemented as proxies, mediators and commands respectively.
That said, the model implementation can be further abstracted and represented using a Proxy and Data Object (a.k.a Value Object) combination. For example, the CarModel properties could be declared in a car value object class and the setter and getter methods for the properties could be implemented in the proxy. See the Proxies section in the PMVC best practices document:
http://puremvc.org/pages/docs/praxis/PureMVC_Implementation_Idioms_and_Best_Practices-1.5.swf
The value object is useful with persistent data — e.g. if car data was stored in a database or as a shared object. However, to keep things simple, you can implement the whole CarModel in the proxy class as well. Hope I didn’t confuse the situation even more.
–chandima
Thanks Chandima, I found your explanations very intuitive and the PureMVC Best Practices document is making sense.
So flow goes FlashEvent > Mediator > Notification > Command > Proxy > ValueObject.
Can I pick your brain once more … If the ValueObject wants to update the View (or other ValueObjects) should it use ApplicationFacade.getInstance().notifyObservers(), utilise it’s Proxy somehow or communicate directly?
I’m still thinking about cars btw, and basic collision between ValueObject instances.
Many thanks.
Rob, my preference is for the Value Object to communicate through its proxy whenever possible as the proxy implements the Notification interface.
I like to think of the value object + proxy relationship as being symmetrical to the UI component + mediator relationship.
In the view, the mediator listens for flash events from UI components. Similarly, if the Value Object class implements the IEventDispatcher interface (e.g. by extending the EventDispatcher class), proxies can register with their value objects to listen for Flash Events from them and generate Notifications.
I think this is what Cliff Hall had in mind when he designed PMVC, but I could be wrong.
For collision detection, I like to have a separate collision detection proxy that keeps a collection of all the Sprites in the application and generate a collision Notification if there is one.
Hey thanks for the great walk through (and book!), I updated your example to work with the latest AS3 version of PureMVC (2.0.3)
http://blog.vixiom.com/uploads/mvc_minimalist_v2.zip
Updating the example to the new package hierarchy has been on my todo list for awhile. Now, thanks to Alastair, I can take it off.
“The StageMediator mediator could have directly updated the model in step 5 through the KeyDataProxy proxy, without going through a command object. However, this introduces a tighter coupling between the Mediator and Proxy that should best be avoided.”
In the sample app “EmployeeAdmin” on PMVC website, the mediator access proxy to update data, quite a few times. Don’t understand why they did this!
Hi Andrew, I’ve become more pragmatic about this issue lately. It depends on where you decide to put the application logic - either in a command or in the proxy.
There is an advantage to putting application logic in a command object as you can swap out a command if you decide to handle user gestures in a different way. This is in line with the intended purpose of a controller in the MVC pattern. The controller should be a “strategy” for handling user gestures (i.e. concrete strategy in a strategy pattern). In contrast, code modifications would be required if the logic was in the Proxy.
Accessing the proxy through a command in all cases is theoretically sound but it does introduce an additional command object. Keeping the number of commands down to a manageable level should also be a consideration.
Hi chandima, thanks for the timely reply! I’m a novice to PMVC and I’m trying to get the instruction proposed by PMVC.
I do see this behavior is accepted by PMVC best practice document. Quite possible that the logic involving multiply proxies should be put into the Command. I have to make it very clearly; you know, in a development team, if no convention or discipline in our mind, folks tend to adopt shortcut by putting all logic in Mediator, which results an useless Control tier.
Once upon a time we were in the KISS era (Keep It Simple Stupid), then came the golden years of OOP. Today we have crossed the KICS era (Keep It Complicated Stupid)
@Brad. Completely agree with KICS statement. I prefer to use my own no-frills MVCS implementation with AS 3.0 Event system.
An excellent tutorial, thankyou
I’ve also tried to do my bit for the PureMVC community by writing a tutorial of my own.
Check it out at http://www.actionscriptdeveloper.co.uk/puremvc-tutorial-flex-puremvc-jabber-and-xiff-3-introduction/
Enjoy,
Dave Keen
http://www.actionscriptdeveloper.co.uk