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. ;-)

  1. 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

  2. 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.

  3. 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 ApplicationControlBar containing a TextInput , and a Button or something else. Then create just one Mediator for the ApplicationControlBar called ApplicationControlBarMediator and refer to the missing components casted as a second, third, etc. View Component.

  4. 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.

  5. 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 -> Mediator

    Even 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).

  6. 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.

  7. 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 PureMVC Proxy, just a location based on a Proxy to organize the server calls such as HTTPServices, RemoteObjects or whatever.

    For example: To call a server-side RemoteObject to login a user create Proxy called LoginProxy. The LoginProxy does 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 – the LoginProxy.

  8. 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 created destroy() method to remove the ViewComponent including all listeners, timer, references, etc. for a successful garbage collection.

  9. 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.

  10. Courseware available

  11. 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 ;-) !

36 Responses to “10 tips for working with PureMVC”

  1. Ivan Says:

    Can you please explain in more detail why it’s a bad practice to change a Proxy from Mediator?
    Thanks.

  2. sectore Says:

    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

  3. Guy Boertje Says:

    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?

  4. sectore Says:

    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

  5. Guy Boertje Says:

    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

  6. sectore Says:

    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 getUser is located server-side (org.puremvc.as3.demos.flex.weborb.login.LoginFacade) and the RemoteObject named loginService is listen to its ResultEvent.RESULT. The loginService knows about it using the attribute called loginService.source which is defined within the LoginProxy (line 42).

    I hope it helps ;-)

    -sectore

  7. Guy Boertje Says:

    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?

  8. sectore Says:

    Guy,

    that’s right, the org.puremvc.as3.demos.flex.weborb.login.LoginFacade is located on server side (check the *.zip -> Folder named “Services” and its readme-file).

    And don’t be confused about the RemoteObject ;-) . To simplify the example mentioned above it uses addEventListener() to receive any notifications of a ResultEvent.RESULT or FaultEvent.FAULT.

    It’s a common way using an AsyncToken and a Responder as well, because the AsyncToken is a return value of a RemoteObject calling a remote service. For this purpose you can refactor the getUser() within LoginProxy as 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

  9. Guy Boertje Says:

    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.”

  10. duzengqiang Says:

    Hi sectore,
    Good article,and I have translated it into Chinese.
    http://www.duzengqiang.com/blog/article.asp?id=674
    Have fun!

  11. Eric La Rocca Says:

    Thanks Jens for your precious post.

    The french translation is now online at
    http://www.polemedia.com/puremvc/10trucs.htm

  12. 冰山上的播客 » Blog Archive Says:

    [...] 原文地址: http://www.websector.de/blog/2007/12/25/10-tips-for-working-with-puremvc/ [...]

  13. ashier.com » Blog Archive » Hello World for PureMVC with AMFPHP in FlashCS3 Says:

    [...] 10 tips for working with PureMVC SilVaFUG Flex Application Frameworks Presentation [...]

  14. ashier.com » Blog Archive » PureMVC with AMFPHP in FlashCS3 - Hello World App Says:

    [...] 10 tips for working with PureMVC SilVaFUG Flex Application Frameworks Presentation [...]

  15. Rob Says:

    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.

  16. sectore Says:

    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

  17. Théatre magique » Blog Archive » First steps in PureMVC Says:

    [...] (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 [...]

  18. soenke Says:

    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!

  19. sectore Says:

    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

  20. Mediator strategy in PureMVC « lukesh +interactive Says:

    [...] 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 [...]

  21. Gabriel Says:

    Hi Jens,
    Thanks for such a great post!
    BTW, the courseware link is dead, do you know where can I get it?

  22. sectore Says:

    @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

  23. Tutorials | PureMVC Roundup « Flash Enabled Blog Says:

    [...] 10 tips for working with PureMVC [...]

  24. [??]-MVC Framework ~ PureMVC « [MitchBox] - ?????? Says:

    [...] ????????????????????????1. Getting Started with the PureMVC Startup Manager – 1, 2, 32. 10 tips for working with PureMVC [...]

  25. Flex Labs » Post Topic » 10 tips for working with PureMVC by Jens Krause Says:

    [...] English Version – 10 tips for working with PureMVC [...]

  26. nicemandan Says:

    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?

  27. MVC Frameworks for Flex | theflexmagazine.com Says:

    [...] 10 tips for working with PureMVC [...]

  28. Introduction to PureMVC | ShoutWaves Says:

    [...] http://www.websector.de/blog/2007/12/25/10-tips-for-working-with-puremvc/ , 10 tips for working with PureMVC [...]

  29. Joy of coding » Introduction to PureMVC Says:

    [...] http://www.websector.de/blog/2007/12/25/10-tips-for-working-with-puremvc/ , 10 tips for working with PureMVC [...]

  30. PureMVC resources | Uplevel e-solutions Says:

    [...] http://www.websector.de/blog/2007/12/25/10-tips-for-working-with-puremvc/ , 10 tips for working with PureMVC [...]

  31. Mariush T. - Flex Developer » Blog Archive » PureMVC in a week Says:

    [...] 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 [...]

  32. Ahmed Nuaman Says:

    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/

  33. PureMvc Links « Geirr Winnem's Blog Says:

    [...] 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 [...]

  34. sideDoor Says:

    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.”

  35. sectore Says:

    @John / sideDoor:

    Every Mediator has only one property viewComponent to 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

  36. PureMVC – ????? ???? | Sewonist.com Says:

    [...] [?? ???] PureMVC – http://www.puremvc.org/ PureMVC Tutorial – http://www.actionscriptdeveloper.co.uk/puremvc-tutorial-flex-puremvc-jabber-and-xiff-3-introduction/ 10 Tips – http://www.websector.de/blog/2007/12/25/10-tips-for-working-with-puremvc/ [...]

Leave a Reply

Follow sectore on Twitter