PureMVC vs. Cairngorm

This post was written by jimrobson on April 10, 2008
Posted Under: Cairngorm, OOAD, PureMVC

UPDATE: A revised version of this comparison has been posted; click here to read it.

I have written favorably about both Cairngorm and PureMVC, and this has led a number of people to ask which framework I prefer. Rather than make a blanket statement that one framework is better than the other, it seems more profitable to take a few moments to discuss some of the strengths and weaknesses of each.

Let’s start by emphasizing that the two frameworks share a number of strengths. Both of them provide conventions that, once learned, enable you to build complex applications faster. Both of them lend themselves (in varying degrees) to team development. Both of them promote some level of code reuse. Both of them help you make applications that are easy to maintain and extend. Both of them will enable you to build applications that any experienced Object-Oriented developer will be able to get up to speed on very quickly. Both of them give you complete control over event flows. (When using native Flex events, you need to be aware of bubbling, and whether there is any native Flex code that is also listening for the event you’re dispatching, but each of these frameworks addresses this issue - PureMVC implements a publish/subscribe system with its notifications, and Cairngorm uses CairngormEvent/CairngormEventDispatcher.)

Having looked at what the two frameworks have in common, let’s now take a look at what makes them different. Since we’re talking about Flex frameworks, I thought it would be fun to put the comparison matrix in an AdvancedDataGrid component:

Framework Comparison AdvancedDataGrid Application

You can open and interact with the matrix here. (Building it wasn’t as much fun as it should have been, but I’ll address that in a future post.)

I’m sure there’s much more that could be said, and I hope that you’ll add your thoughts to this discussion. If you don’t want to post your comments/questions here in the blog, feel free to contact me directly.

Reader Comments

Jim,

I am fully agree with Pros and Cons you mentioned in the matrix. Thanks for sharing your knowledge with us.

#1 
Written By Ashvin Savani - Arckid on April 11th, 2008 @ 10:53 pm

Ashvin,

Thanks for the encouragement!

#2 
Written By jimrobson on April 14th, 2008 @ 8:12 am

Having lately done the PureMVC vs. Cairngorm comparison myself, I tend to agree with what you have. For me, I like PureMVC the best, but they are were alike.

BTW: One “Con” against Cairngorm is the ServiceLocator/remoting stuff. At least it is for me. It seems to bind to FDS, which I do not want.

Thanks for sharing!

#3 
Written By Tech Per on May 11th, 2008 @ 2:49 pm

@Tech Per,

Thanks for the feedback.

Your point about the ServiceLocator is interesting. An advantage of the ServiceLocator is that it can be used with any type of back-end service that will work with Flash: SOAP Web Services, RESTful services, Remoting, or FDS. One nice thing about this is that if you need to change your data source (e.g. move from SOAP to REST), you may not need to touch anything in your Flex code but the ServiceLocator.

#4 
Written By jimrobson on May 13th, 2008 @ 10:56 pm

A comment on the Cairngorm ModelLocator “con”.

I’ve made many enterprise (huge, gigantic, enormous) Flex applications. I’ve learned to boil down the ModelLocator into two very distinct purposes.

1) Each ModelLocator should have one, and only one Array that contains one specific type of VO. For example, if your application had UserVO object, you’d have a UserModelLocator.

2) Each ModelLocator should have all of the functions necessary to find specific VOs by a property. For example, your UserVOs would probably have a property named id. You’d then want to have a “getUserById” method in UserModelLocator.

Rinse and repeat for every major VO type you have.

Now I hear the crowds screaming “but that’s so verbose!”. Actually, if you’ll stick with this, you can massively reduce the rest of the code in your application. Keep reading….

When you send a VO over the wire, you should send only its simple properties, and maybe some small referenced VOs. You should NOT send your entire spider web of VOs. So for example, if your UserVO has a lastInvoice:InvoiceVO property, you shouldn’t send that entire InvoiceVO over with every add/edit/delete user command. Instead, use ISerializable on your VOs. That will allow you to break down the necessary information in your VOs (including that InvoiceVO) into smaller bits, usually ids. For example, the writeOut function could simply read the id of the InvoiceVO and send that.

Now when you get responses back from the server about your InvoiceVO or your UserVO, you can simply use your model’s getUserById or getInvoiceById to grab the appropriate VO.

By having many small ModelLocators that handle a single VO, you’ll greatly reduce the amount of information you send over the wire, therby having less code in Commands and Delegates. You’ll have no confusion over which model a VO goes into, because it always goes into the ModelLocator that has its name, and you’ll group all of the “find this VO” logic into a single file.

You’ll find that this technique is very portable, understandable, and turns the ModelLocators into rubber stamp easy.

#5 
Written By Travis Collins on February 2nd, 2009 @ 10:23 pm

@Travis,

Thanks for the tip! I agree with you on using managed associations, as I’ve written in another post. I also agree with creating special accessor methods for VO collections, though I usually extend the collection classes for this. For example, I’ll create a subclass of ArrayCollection that has a getItemByID() method, and use this collection class for all VOs that have IDs. Your idea of one ModelLocator per VO type is one that I’ll need to think about some more. I don’t see any immediate problem with it, and the fact that you’ve used that approach successfully in a number of large applications tells me that it’s probably a good solution.

#6 
Written By jimrobson on February 3rd, 2009 @ 12:40 pm

Hey Jim, when creating your subclass of ArrayCollection, where would you store it in the file structure. Inside the model folder? Or did you create a separate folder for subclasses? Also, since it’s not good practice to bind directly to VOs, are you using you subclass of ArrayCollection to bind to?

For example in your application mediator

app.resourceList = new ArrayCollection(_resourceProxy.resources);

resources is an array on my proxy. Can you bind to {resourceList.getItemById()} from your view to get a particular VO?

#7 
Written By Tristan on March 17th, 2009 @ 6:15 pm

@Tristan,

I put the collection subclasses in model -> utils, though if you think you’ll need several such classes it might be better to make a dedicated directory, such as model -> collections. And yes, I bind to the collection subclasses, using expressions similar to {resourceList.getItemById()}.

#8 
Written By jimrobson on March 18th, 2009 @ 8:14 am

Trackbacks