10 tips for working with PureMVC
December 25th, 2007
This post is translated into German, Russian, Chinese and French. Thanks a lot to Aleksey, duzengqiang and Eric for the translations!
Jesse Wardens great article called “10 Tips For Working With Cairngorm” has given me the idea to share 10 tips using PureMVC as well. I’ve been using PureMVC intensively for about six months now and – that’s not a secret – I’m loving it. Anyway, all my following opinions are based on my personal experiences only.
-
Think in (Pure)MVC
How do I start using PureMVC? Short answer: Just think in (Pure)MVC! As its named says, PureMVC based on the classic Model-View-Controller design meta-pattern. Using the Facade-pattern you don’t instantiate the core actors directly, but every member of PureMVC has its own and clear defined role:
- Proxies = Model- Mediator and its ViewComponents = View
- Commands = Controller -
Create an API for View Components
A View Component might be a standard UI component (e.g.
DataGrid) or a custom component (e.g. a world within a game) or whatever. Don’t use its public methods directly. In order to change its state or behavior create an API.One of the advantage of PureMVC is to be neutral to the technologies being used. An example: I’ve built a “pure” Flash application based on PureMVC without using the Flex Framework. The same app will be ported to an AIR application for using AIR’s great File system API. The View Components have to be changed using the Flex Framework, but not the Mediators or any other actors of PureMVC.
-
Use one Mediator for multiple View Components
To coordinate more than one View Component closely, use one Mediator only. In other words: Not all Views need a Mediator. For example: Assume a
ApplicationControlBarcontaining aTextInput, and aButtonor something else. Then create just one Mediator for theApplicationControlBarcalledApplicationControlBarMediatorand refer to the missing components casted as a second, third, etc. View Component. -
Let’s Events bubble up
What happens if you don’t want to use multiple View Components within a Mediator? In order to handle user interactions with multiple View Components let’s bubble Events from the nested children of a View Component up.
For example: Clicking any Button within a View Component will fired up a custom Event which the Mediator is listen to. So the Mediator don’t have to know about the existing Button or about any other child of its View Component, just about the custom Event bubbled up.
-
Communicate using Notifications as often as possible
Notifications are the “Events” of PureMVC. For communicating between the three tiers Model, View and Controller use Notifications for the following scenarios as often as possible:
(communication from -> to)
- Mediator -> Proxy (via mapped Commands)
- Proxy -> Mediator
- Proxy -> Command
- Commands -> MediatorEven if it’s possible to retrieve a Proxy from a Mediator, don’t change the Proxy from a Mediator directly rather than sending a Notification using a mapped Command. It’s a bad practice to change a Proxy (Model) from a Mediator (View) directly without using a Command (Controller).
-
Use Commands / MacroCommands as often as possible
Commands are doing the job at the Controller side: Retrieving and interacting Proxies, communicating with Mediators or executing other Commands. Even if a Command used only once or it has only two lines of code, use it as often as possible. To execute a Command once again anywhere or anytime within your application, you have to send just a Notification. In the future it’s easy to enlarge the Command with more complex actions. And – that’s very important – you always know, who the actor for changing the Proxy (Model) is.
Question: Have you had to execute more than one Command in a particular order? Use MacroCommands to execute multiple SubCommands (which means “simple” Commands) sequentially.
-
Use Remote Proxy to send and receive server-side data
To send and receive data between the application tier use Proxies called
Remote Proxies. That’s not a special kind of a PureMVCProxy, just a location based on aProxyto organize the server calls such asHTTPServices,RemoteObjectsor whatever.For example: To call a server-side
RemoteObjectto login a user create Proxy calledLoginProxy. TheLoginProxydoes all the job to communicate with the server-side, which means sending and receiving data. Whenever you’ll change the server-side implementation for the LoginProcess, you’ll have to change one location within your application only – theLoginProxy. -
Remove unused Mediators
In some cases you don’t use a Mediator and its View Components anymore. Then remove the Mediator using
facade.removeMediator(MyMediator.NAME);in conjunction with a self createddestroy()method to remove the ViewComponent including all listeners, timer, references, etc. for a successful garbage collection. -
The Power of VO’s (Value Objects)
The place to store data within the Model are the Proxies – that’s right. The View Components have no need to know the Facade and the rest of the PureMVC application – that’s right, too. This means that the View Component has no access to the Model data directly.
To avoid this issue store within the View Component a reference to the data using Value Objects (VO’s). The VO’s are not a core actor of PureMVC and in conjunction with the Data Binding feature of Flex are a powerful way to react changes in the Model data without breaking rules.
-
Courseware available
Cliff Hall has done an awesome job: You’ll find not only excellent documentations about the “Framework Overview“, “Best Practices” and a “Conceptual Diagram“, also a very, very, very helpful Courseware. Check it out!
Enjoy PureMVC and Happy Holidays
!


December 27th, 2007 at 8:26 am
Can you please explain in more detail why it’s a bad practice to change a Proxy from Mediator?
Thanks.
December 27th, 2007 at 9:50 am
Ivan,
with a Mediator as a part of the View and a Proxy as a part of the Model it’s a good practice using a Command (which is a part of the Controller) to modify the Proxy (Model), which means that you are going a common way using the MVC paradigm to change the Model data (View -> Controller -> Model). When modifying a Proxy (Model) directly from a Mediator (View) the job of the Controller would be ignored.
Furthermore, with using a Command you always know, who the data within a Proxy has changed.
-sectore
December 29th, 2007 at 5:42 pm
Hi,
I’m trying to refactor my first flex app. It is a big bowl of spaghetti (developed from API docs and no internet to refer to). I’m stuck. I have looked at the cairngorm based Pomodo example (has RubyAMF which I want to use) and pureMVC Cafe Townsend app (has pure MVC which I want to use). I would appreciate a hint on whether its better to start with the VOs and Model or the View components. Any ideas?
December 29th, 2007 at 6:42 pm
Guy,
that’s not an easy question to answer. And it depends on the needs of your project. Anyway, I think it’s a good idea to start with the Model (Proxies) and VO’s to organize well structured application data and business logic.
P.S. Check out my “WebORB for PHP Login Sample” for using PureMVC and Flex Remoting based on WebORB for PHP (which is like using RubyAMF), too.
-sectore
December 30th, 2007 at 2:51 am
Jens,
Thanks. I looked at the example. Ok, explains alot, but what isn’t clear is:
1. In “facade.registerMediator(new LoginPanelMediator(app.login));” where/what is the app referencing?
2. In the AMF service _loginService is the getUser method defined serverside? How does the RemoteObject ‘know’ of this method? I can’t see it declared anywhere. Ta, Guy
December 30th, 2007 at 12:12 pm
Guy,
1.) app is the ViewComponent (an instance of DemoAS3FlexWebORBLogin) of the ApplicationMediator using the getter method
protected function get app(): DemoAS3FlexWebORBLogin ...(ApplicationMediator.as, line 136)2.) That’s right. The method called
getUseris located server-side (org.puremvc.as3.demos.flex.weborb.login.LoginFacade) and the RemoteObject namedloginServiceis listen to itsResultEvent.RESULT. TheloginServiceknows about it using the attribute calledloginService.sourcewhich is defined within theLoginProxy(line 42).I hope it helps
-sectore
December 31st, 2007 at 2:58 pm
Jens,
I presume that (org.puremvc.as3.demos.flex.weborb.login.LoginFacade) is PHP code and not a missing Flex class from the source. I have not read all of the RemoteObject api docs and am having problems understanding the binding of an event listener to the getUser method of the RO, e.g. _loginService.getUser.addEventListener() when the CafeTownsend and Pomodo examples use IResponder with a Delegate, which I kind of get. Where in the flex source is it declared that getUser is a method of the RO?
January 1st, 2008 at 4:35 pm
Guy,
that’s right, the
org.puremvc.as3.demos.flex.weborb.login.LoginFacadeis located on server side (check the *.zip -> Folder named “Services” and its readme-file).And don’t be confused about the
. To simplify the example mentioned above it uses
RemoteObjectaddEventListener()to receive any notifications of aResultEvent.RESULTorFaultEvent.FAULT.It’s a common way using an
AsyncTokenand aResponderas well, because theAsyncTokenis a return value of aRemoteObjectcalling a remote service. For this purpose you can refactor thegetUser()withinLoginProxyas follow:public function getUser(vo:LoginVO):void
{
var token : AsyncToken = loginService.getUser(vo);
token.addResponder(new Responder(getUserResult, getUserFailed));
}
Your last question: The RemoteObject knows about its services using the source value declared by its attribute “
source”-sectore
January 2nd, 2008 at 3:06 pm
Hi Jens,
Thanks, I found the (new Responder…) line useful.
I also found the answer to my “ro.method” definition mental block in the Flex API docs. Look for -#- brackets. AbstractOperation extends EventDispatcher via AbstractInvoker so thats why ro.method.addEventListener works.
In AbstactService
“public final function getOperation(name:String):AbstractOperation
Returns an Operation of the given name. If the Operation wasn’t been created beforehand, it is created during this call.
-#-
Operations are usually accessible by simply naming them after the service variable (myService.someOperation)
-#-
, but if your Operation name happens to match a defined method on the service (like setCredentials), you can use this method to get the Operation instead.”
January 4th, 2008 at 7:21 am
Hi sectore,
Good article,and I have translated it into Chinese.
http://www.duzengqiang.com/blog/article.asp?id=674
Have fun!
January 4th, 2008 at 7:28 pm
Thanks Jens for your precious post.
The french translation is now online at
http://www.polemedia.com/puremvc/10trucs.htm
January 7th, 2008 at 4:22 am
[...] 原文地å€: http://www.websector.de/blog/2007/12/25/10-tips-for-working-with-puremvc/ [...]
January 19th, 2008 at 11:54 am
[...] 10 tips for working with PureMVC SilVaFUG Flex Application Frameworks Presentation [...]
January 19th, 2008 at 12:02 pm
[...] 10 tips for working with PureMVC SilVaFUG Flex Application Frameworks Presentation [...]
January 28th, 2008 at 6:13 am
You said “The View Components have to be changed using the Flex Framework, but not the Mediators or any other actors of PureMVC.” in Tip 2. Would you elaborate on why you don’t have to modify the mediators when the API to the components used in Flash and Flex are different? Do you create an API in your view so the mediator does not need to talk to the components directly? Clarification please. Thanks.
February 16th, 2008 at 12:57 pm
Rob,
that’s right.
In some cases it could be a good idea to create a self defined API to manipulate the view components. So you can replace a view components without changing the Mediator.
Imagine a simple view component (e.g. Canvas), which includes a DataGrid. To populate this DataGrid the Mediator has a method called viewComponent.setUserData(data), which passes the ViewComponent only the data (e.g. an ArrayCollection) without defining the way to handle it. The ViewComponent populate the DataGrid using its method called “setData(data: ArrayCollection)”. So you can change the ViewComponents DataGrid with a self created component without changing the Mediator.
-Jens
March 22nd, 2008 at 10:55 am
[...] (some of) my many questions as everything was hazy in the beginning. Also, I have come across 10 tips for working with PureMVC which is very [...]
April 18th, 2008 at 11:13 am
hi Jens,
Remove unused Mediators:
you can easily use the onRemove method to clean up your Mediator and
remove its view components if necessary
override public function onRemove():void
{
//destroy//
}
some greate tips! thanks a lot!
April 18th, 2008 at 12:45 pm
Sönke,
you’re right!
That’s a new feature of PureMVC v.2.0 and later. It wasn’t available at the time of writing these tips
Anyway, it’s a good hint – thx!
-Jens
June 12th, 2008 at 1:41 pm
[...] implemented PureMVC in both Flash and Flex projects and I’ve noticed that #3 of this post really applies. I mean really applies. As a general philosophy, I believe it’s better to [...]
July 16th, 2008 at 1:05 pm
Hi Jens,
Thanks for such a great post!
BTW, the courseware link is dead, do you know where can I get it?
July 17th, 2008 at 8:42 am
@Gabriel: Sorry about the broken link. At the PureMVC forum you will find a category named “Architecture 101 Courseware”, maybe you will get there more information about it.
-Jens
July 22nd, 2008 at 12:14 am
[...] 10 tips for working with PureMVC [...]
September 29th, 2008 at 5:21 pm
[...] ????????????????????????1. Getting Started with the PureMVC Startup Manager – 1, 2, 32. 10 tips for working with PureMVC [...]
October 29th, 2008 at 12:05 pm
[...] English Version – 10 tips for working with PureMVC [...]
December 22nd, 2008 at 11:38 pm
Hi,
I’m switching over a game using SmartFox’s chat server to PureMVC. I’ve already got a request / command architecture working with the server.
Should I be using these commands to simply broadcast notifications or would these commands require some sort of RemoteProxy object?
January 7th, 2009 at 4:15 pm
[...] 10 tips for working with PureMVC [...]
March 8th, 2009 at 9:16 pm
[...] http://www.websector.de/blog/2007/12/25/10-tips-for-working-with-puremvc/ , 10 tips for working with PureMVC [...]
March 17th, 2009 at 7:37 pm
[...] http://www.websector.de/blog/2007/12/25/10-tips-for-working-with-puremvc/ , 10 tips for working with PureMVC [...]
March 18th, 2009 at 10:35 pm
[...] http://www.websector.de/blog/2007/12/25/10-tips-for-working-with-puremvc/ , 10 tips for working with PureMVC [...]
May 21st, 2009 at 2:17 pm
[...] Minimalist MVC example using the PureMVC 10 tips for working with PureMVC Flex, PureMVC, Jabber and XIFF 3 PureMVC Notifications PureMVC Roundup Flex, Coldfusion and MySQL [...]
May 26th, 2009 at 8:53 pm
Hey, I don’t know if this is of any use, but I wrote an article on PureMVC: http://ahmednuaman.com/blog/2009/05/18/my-first-tutorial/
November 11th, 2009 at 10:51 am
[...] links i learned from: PureMVC tutorial on activetuts Understanding pureMVC Jens Krause’s Blog 10 tips for working with pureMvc WS-Blog » A basic PureMVC MultiCore AS3 example using Pipes Utility and Modules. Frédéric [...]
January 9th, 2010 at 2:08 am
Thanks for the article!
In step #3, you said:
“Then create just one Mediator for the ApplicationControlBar called ApplicationControlBarMediator and refer to the missing components casted as a second, third, etc. View Component.”
I get the first part, create one Mediator to service a group of components, but what exactly do you mean by:
“…and refer to the missing components casted as a second, third, etc. View Component.”
January 10th, 2010 at 12:17 pm
@John / sideDoor:
Every Mediator has only one property
viewComponentto reference it’s view component by default. You may use an own getter method to cast this view object to a type.However, it does not mean, that a Mediator have to mediates one view component only
To avoid creating tons of Mediators for handling tons of view components a Mediator could have two, three or more properties (references) to other view components.
-Jens