Minimalist MVC example using the PureMVC Framework
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 among others.
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
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 | 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
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 | 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
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 | 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
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 | 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
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 | 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
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 | 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.

Bill Sanders
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.
Great resource Chandima – thanks for putting it together.
As well as updating the package hierarchy, the other essential change that Alastair made is to the StageMediator.
In the original we have:
// pass the viewComponent to the superclass
super(viewComponent);
This raises the following error at compile time:
Description Resource Path Location Type
1067: Implicit coercion of a value of type flash.display:Stage to an unrelated type String. StageMediator.as /MVC_minimalist_v1/src/view line 18 Flex Problem
Alastair changes this to:
super( NAME, viewComponent );
Which fixes things.
Thanks again – a great intro to PureMVC.
@Chris, Thanks for the note. I believe that issue is due to an API change in PureMVC Release 2.0. The article was written for PureMVC 1.6 way back in 2007 and I haven’t updated it since. I should make a note at the end to recommend that readers use Alastair’s updated code.
Cool. Thanks. I figured as much. I only saw Alastair’s link after I’d fixed the problem myself, which was actually a great way to dig into PureMVC.
“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
Hi Chandima-
I had to alter a line in the StageMediator class to get the code to compile. Where it calls the super(), it had a conflict in that the super constructor requires a string and then a display object. In this example code there is only a display object (the stage) being passed. I was able to pass null and then Stage, and it worked. I’m surprised others didn’t encounter this. Thanks though, the tutorial helped get from totally in the dark to partially in the dark!
Hi Arlo,
The minimalist example is behind the times somewhat as it was written for PureMVVC version 1.x. PureMVC version 2.x has some interface changes in addition to changes in the package hierarchy. As you noted, the Mediator constructor now requires two parameters – the mediator name and the view component. Previously, only the view component was required. Thanks for catching this.
Alastair has updated the minimalist example for PureMVC 2.0.3. Check it out at:
http://blog.vixiom.com/2008/04/01/actionscript-mvc-minimalist-example-for-puremvc-203/
Chandima.
This is a great article indeed… very informative.
My shameless plug is flashMVC which is a minimalistic MVC framework that is very customizable yet simple (takes roughly 6 lines of code to setup a full MVC hello world app!)
http://www.jadbox.com/flashmvc/
Please comment and let me know your thoughts!
omg.. good work, brother
hi there i have a question concerning the MVC pattern. I read the Actionscript 3 DP and the other on, advanced AS3 with dP…
the thing is there is something very weird i cannot answer and understand after reading the 2 books!!!
- does the model updates the view(s) directly without going through the controller?
- a controller does have one view only or is it possible to have more?
these questions are just pissing me off, meaning i have the feeling i didn’t catch the whole sense of the MVC pattern
thank you so much
@gropapa, I’ll answer the questions based on the MVC examples from the AS3 design pattern books you mention.
- does the model updates the view(s) directly without going through the controller?
The model does not update views – the views read application state and data from the model and update themselves. The model shouldn’t know anything about how views are implemented – the model simply notifies registered views when things have changed. Views then *read* data directly from the model (don’t go through a controller).
Views don’t *write* to the model directly, but to so indirectly through a “controller.” The controller is a “strategy” for handling user gestures ( e.g. button click on a view ).
- a controller does have one view only or is it possible to have more?
A single controller instance can be shared between multiple views.
This brings up an important issue: Controllers should not have state, only logic ( for sharing to work ). This is important for PureMVC as well because commands are the controllers and as explained in the PureMVC docs – commands shouldn’t have state.
I hope this didn’t further confuse the situation.
Hi Chandima,
i really thank you for answering me, it is very usefull for me.
About the model updating the views, yeah maybe i wrote my message too fast (and maybe because english is not my first language:))
Yes obviously the model will dispatch events listened by the views.
I don’t know nothing about pureMVC but i guess i’ll have to have a look on it!
Thank you very much!
Hi. I want to implement MVC in C#.Net. I have multiple view and single controller if my view my change then that particular change should effect on other view. Second I have two object one is for docking and other is for undocking mode I want to show same object for docking to MDI and un-docking seperate.
Thanks,
Sadaqat
Hi Sadaqat,
I’m assuming that you are using the C# version of PureMVC available for download here:
http://puremvc.org/component/option,com_wrapper/Itemid,147/
My C# experience is minimal, so I’ll try to give a generic answer. When a view change requires changes in application state or data, the associated mediator should modify the model. You can do this directly by accessing the proxy or through a command. The method in the proxy that updates the model has to dispatch a “Notification” that informs interested views that a change has taken place ( as in the KEYUPDATE notification in KeyDataProxy in the above example ). The view mediators that need to change together need to intercept the notification and change accordingly.
Outstanding post. Great example to help someone get their head around the PMVC architecture. Bravo!!
I’m new to this, and I couldn’t work out how to get this example (well, v2 of it) to run in Flex Builder… How do I make it run Main.as, or whatever? It just kept telling me there was nothing to run, and when I tried to setup the application in the project settings, none of the files in this example appear in the list.
@Big Barry
You can make this work in Flex Builder. I’ve put together a Flex Project Archive of version 2 by @Alastair (saves you a few steps).
http://www.as3dp.com/wp-content/uploads/2009/01/puremvc_minimalist.zip
In Flex Builder:
1. “File > Import > Flex Builder > Flex Project” — and hit the next button.
2. Browse to the downloaded archive file and hit the Finish button.
3. Download the PureMVC SWC from http://trac.puremvc.org/PureMVC_AS3/wiki/Downloads
4. Install it into your project library path as described http://trac.puremvc.org/PureMVC_AS3/wiki/Installation
5. As example doesn’t have a UI, you must run it in debug mode “Run > Debug” or Command-F11 ( on a mac ) to view the “trace” output.
Hi Chandima,
great post indeed! Thank’s alot for the help.
@monkeystation I’m pleasantly surprised that this post is still useful. This speaks volumes about the versatility of the PureMVC framework and Cliff’s stewardship of the project. The recent ports to Objective-C and Ruby are pretty exciting.
This post is still very helpful – made me understand the pureMVC framework a lot better.
Great Post!
I don’t know. I’ve got to go with Brad and GG on this: It’s stupid complicated. I’ve been building complex Flash and Flex apps for ten years, and there’s never been any need for anything like Cairngorm or PureMVC. A simple MVC structure with bubbling events gluing it together is all that’s ever required.
Even the minimalist example in the O’Reilly book is ridiculous, with controller code muddying both the model and the view. And give me one good reason why I should program to interfaces, why my controller should be typed as something other than Controller, my model typed as something other than Model.
@joe, the learning curve is the price you pay when you adopt a framework. The advantage is the hope that it pays off in the long run when handling change in your app when new requirements are introduced. I’ll address the issues you have brought up.
Complex applications have multiple models. Let’s take a quick example. If you are developing a space invaders type game there will be an application model that keeps track of application state such as current level, current score etc. How do we implement the hundreds of alien ships? Each alien ship should have its own model to keep track of its current state such as position, damage taken etc. The reason to use multiple models is to separate responsibilities. Each model is responsible for one overall concept or object. PureMVC is built from the ground-up to handle multiple models using proxies and value objects. Although possible, handling all the objects in an application using a single model will make the model huge and unwieldy. Most of the Flash/Flex components are built using an MVC architecture. So, we have multiple models under the hood of our applications, but we don’t see them.
The controller is an additional layer of abstraction in the MVC triad. It is by no means a necessity in a well-designed application. In PureMVC, views can access proxies directly without using controller commands. Flex data binding is an MV architecture and does away with the controller altogether. It depends on where you as a developer decides to put the logic that handles user gestures: in a controller or in the model. Controllers have advantages in that they can be swapped out easily to change application behavior in response to user input and events. This is a much safer way of handling change than modifying model code. I’m not sure how you can get away with only one type of controller in anything other than the most simplest of apps. Handling all user events through one large controller will introduce a huge bottleneck.
The primary advantage of programming to an interface is to keep the dependency relationships loose and not get tied down to a particular implementation of a class. I‘m sure that you have coded some amazing applications using the built-in classes. I’m also certain that you have looked at the AS3 documentation to figure out the behavior of those classes. What do you think the AS3 documentation is? It is an interface definition. When you use a TextField instance in your app, you are coding to the well-defined interface of the TextField class. Adobe could change how the TextField class is implemented tomorrow (change the C++ code or whatever they use – we don’t care ), but, your app will not break. We program to interfaces all the time, but don’t realize it sometimes.
Design patterns, frameworks and even OOP are not for everyone and every situation. I’ve seen plenty of functional non-OOP Flash AS2 apps with procedural code in the timeline to believe that. That being said, applications that have long life cycles cannot be viewed in snapshots in time. They are constantly changing and evolving for the better. Those of us who take that long-term view, put a premium on handling change elegantly without pulling our hair out.
I’m trying to learn pureMVC for python without any knowledge of flex. I only know Python. It would be nice if there a version of this minimal example that worked with python. I may try to get this to work with python as an exercise. I downloaded the example and there are a lot of files other than the view, model, controller and facade. I’m having to figure out what all those other things do. It seems like most of the documentation offers only overviews of the theory behind pureMVC. I’m having to figure everything out from pure Source Code. It would also be nice if there were a pureMVC skeleton project that you just add stuff to with comments where you need to add things. And an example line so you only have to change that line because usually there is a specific function that needs to be added at a particular place
Hi Mark, I’m with you on the lack of simple examples for the PureMVC ports. Cliff did a really good job with the docs for the overall framework. However, the lack of docs for the ports is an issue. I’m not a Python person, but try the Python port forum on the puremvc site.
http://forums.puremvc.org/index.php?board=18.0
I´m still reading the Post and have tried to click on 3 different linked diagrams that are no longer update, or to be found in Internet.
Just wanted to let you know. It would be a great help to illustrate and follow the explanation.
Thanks!
Hi Gustavo, It looks like the puremvc.org site is down at the moment. Please check back – the links should work. Sorry for the inconvenience.
Update: The links to the PureMVC conceptual diagram and other resources on the PureMVC site were indeed incorrect as you pointed out. I’ve fixed them now.
Thanks for this excellent tutorial. One thing that I keep wondering about is what kind of applications really lend themselves to developing with pureMVC (or any other framework). What’s the advantage of pureMVC? There’s a lot of extra code, even just pressing a button will take days to code so I don’t really see the point
Hi Henk, I do agree that using a framework requires more code and you have to adhere to a particular way of doing things. The short answer is that a framework will be overkill for a simple application that has a short life cycle. A framework shows its strength when applications go through several iterations of development and refactoring, especially when multiple developers are involved.
Frameworks generally provide loose coupling to manage different pieces that make up an application. The pieces can be user interface components like buttons and text fields on the view side, or data or logic on the model side. The Framework provides a particular way of “plumbing” pieces together to enable them to communicate and work together effectively.
I guess you can extend the plumbing analogy a little bit. A framework is like the plumbing in a house in some senses. If the sink in your bathroom is broken or you want to put in a fancy faucet, you can just swop out the old one and install it (i.e. swapping a UI component). You don’t have to mess with the rest of the plumbing in the house. You can even add a whole new bathroom by forking the water supply pipe (i.e. adding a new Mediator with several UI components).
PureMVC provides an added advantage in that it is language agnostic. It doesn’t rely on language internals like Flex Binding. This makes for more work, but ensures that the framework stays the same when ported to other language. So, you learn PureMVC and can use it in AS3, Flash Lite, C# and all the other ports without an additional learning curve.
Really Great post!!!
It had really let me understand PureMVC framework. I am new to this framework and it had provided me a great start.
Thanks
Excellent post. Can’t wait to see some more advanced examples using pureMVC.
Thanks for this post, it is still relevant and very helpful!
Also enjoyed your patterns book, great read, suspenseful and I didn’t see surprise ending coming at all!
Great stuff,
sd
@sideDoor unfortunately, our design patterns book falls into the non-fiction category. We should try a little more suspense, intrigue and flowery language in our blog posts
Thanks for the note and I’m glad that you found the book useful.
Thanks very much for this, it’s exactly what I needed to get my head around things. I am now re-reading the PureMVC Best Practices and it makes so much more sense!
http://scansani.org/data/cars-pmvc.zip find posted my own proposal for the porting of the Cars example (cfr. ActionScript 3.0 Design Patterns http://www.adobe.com/devnet/actionscript/articles/ora_as3_design_patterns.html) to PureMVC, hope it can be handy to someone.
please also feel free to comment!
tnx
f
Thanks @francescop very helpful indeed!
Hi!
I am reading your book “Actionscript 3.0 Design Pattern”!
After that I want to learn a framework for as3/flex. I find pureMVC and Cairngorm are very popular.
Which one should I choose as a beginner?Can you give me some suggestions? Thank you!
@linghong Hsueh, I don’t think Cairngorm is actively developed anymore. Robotlegs is very popular as is the Mate framework. I would recommend looking at some of the example apps in all the frameworks, including PureMVC, and picking the one that is easiest to grasp and makes most sense to you.
Thank you for your suggestion!
From your suggestion,I searched the Robotlegs and Mate,and found an article posted by Tony Hillerson.
http://insideria.com/2009/01/frameworkquest-2008-part-6-the.html
He gave the conclusion of framework quest and also gave a twitter sample with the four frameworks. Mate framework gets the highest score.
I also saw something about the Robotlegs.It is a pure AS3 framework as is Mate the pure MXML framework.
So I decide to learn something about Mate, Robotlegs and pureMVC after finishing your book.
Your suggestion is exactly the current trend of the AS3/Flex frameworks!
Thank you for your instruction again!
Chandima, in objective C development there is the concept of a ‘viewController’. Can you think of what the corresponding element would be in a AS3 puremvc based application?
@Eco_bach: I think the corresponding pureMVC element to a viewController will be a ‘mediator’. However, I’m not familiar with objective-c and don’t know the context of use for a viewController.
In PureMVC, the mediator doesn’t act as a controller, but mediates communication between UI components and the rest of the application. PureMVC mediators encapsulate view components (ui elements) and handle their creation, destruction and events.
Mediators usually fire off notifications in response to ui events (user gestures). Commands are bound to notifications and they invoke a predetermined behavior in response to a notification. From an MVC standpoint, the commands in PureMVC act as controllers.
I hope this info will help you determine if the mediator is equivalent to an objective-c viewcontroller.
You may find one of my recent posts on the classic MVC pattern interesting. It argues that the classic MVC pattern cannot be implemented in AS3 as views cannot be separated from their controllers when dealing with AS3 view components.
http://www.as3dp.com/2010/03/01/separated-presentation-the-classic-model-view-controller-pattern/
Thanks Chandima, will read your post.
Hi Chandima,
I’m rediscovering PureMVC, and trying to analyse best practices before embarking on a project, best done with simple examples like this one. Am aware this is an old example, but it’s still very useful, thanks!
One thing I’m trying to get right, is the balance between simplicity and correct use of the framework and I’d love your opinion on something.
In your example is the assumption that we have to store the last keypressed for some reason(maybe to store state, or be able to implement undo in future or something?) Because if we didn’t need to store the last keypressed, i’m wondering why the Command module wouldn’t dispatch KEYUPDATE, and the View wouldn’t just listen to this notification directly from the command module?
In fact, when we’re talking about user input and we’re certain this input is meant to do something visually, could the mediator do it directly without requiring a command module at all?
An example to illustrate my question – say we have coded a toggle audio button component, is it still okay for the button to toggle its own visual state, and dispatch an event to the Mediator which THEN passes up a notification to the command module for it to deal with toggling the audio?
OR – would it best practice in PureMVC for this button to pass up a ‘CLICK’ event to the Mediator and then go through the whole process of Mediator->Command->Proxy->Mediator which would then tell the toggle button to update its visual state? (And on route I guess the Command would deal with toggling the audio)
The first option seems simpler to me, but on the other hand I could see reasons why the second could make sense in some situations(for example if it was a play/pause toggle button, and we only want the visual state to update once the media has begun playing)
I guess my question is – would your opinion be that best practice in PureMVC would involve some KISS common sense or is it strict, i.e. every View event requires the command module to get involved?
Anyway great tutorial, thankyou.
Hi Craig,
You are absolutely correct! There is no need to save the last key pressed unless you want to save that state for some reason.
I think my intention was to demonstrate the complete notification workflow in the example. In doing so, I neglected to point out alternate ways of accomplishing the same tasks.
1. There is no need for a view to fire off a notification in response to a user gesture unless other views and models are interested in it. In the example, since there is only one view (StageMediator) it could have intercepted the event and traced the keycode in the onKeyDownEvent method itself. If there were two views: One listening to keydown events (KeyDownMediator) and the other tracing it (KeyDisplayMediator), then the workflow in the example makes sense. Even in this case, if KeyDownMediator and KeyDisplayMediator were child views of StageMediator (hierarchical views), you can let the keydown event bubble up from KeyDisplayMediator, intercept it in StageMediator and call KeyDisplayMediator to display it. Keeping all interactions within the view hierarchy.
2. Views can update the model directly without going through a controller. I was a little hard headed about this initially as it introduces a dependency between views and models. However, I’ve become more pragmatic about this. Primarily to reduce the number of command objects. One of the big issues with the PureMVC framework are the large number of commands that are required for even a medium sized app.
Hope this answers your questions. Make sure you use PureMVC multicore for your apps.