So after reading “Professional Cairngorm” I decided that I would try using Cairngorm on my next project. Well that project is is the final stages of completion and I’d like to share my thoughts.
The project was a dynamically driven Flex app embedded in a web-browser that could also run on AIR. The application was read-only and did not collect data from the user but simply presented data one way. This app consisted of a your typical main screen, featuring configurable “portlets” that gave teasers into the deeper content contained within. It also had primary top navigation each of which drove to sub-screens which could render their data-sets in various customizable layout views, each of which having its own set of second level navigation to navigate within that sub screen. The data was stored in an XML implementation of an “Content Store” interface which could also be swapped out with a SQLite or web-service backed version if necessary. The lower level service layer that stored and managed all of the content as well as the navigation meta-data was wired together using Spring Actionscript and also leveraged other libraries like AS3 Commons.
For the application logic itself (i.e. how the views render, how the user navigates around, what screen renders what data etc) was all handled by using Caringorm 2.2.
By default, Cairngorm seems to drive the developer to be extremely granular with their Command, CairngormEvent and Delegate declarations. What this means is that if you are not careful, you will end up with an absolute overload of classes for a simple application. Instead I took the approach consolidating domain related functionality into larger Delegate classes which could handle more than one type of small specific operation. My Delegate classes abstracted away my lower level service layer (where the content and navigation meta-data was stored) away from the application and fulfilled its contracts through the delivery of VOs to the commands, subsequently to the model and finally to the views via Flex data binding.
I also tried to limit the number of events down to a total of four, one for bootstrapping Spring, one for handling a screen change, one for rendering the correct body and finally one for launching external resources. The number of VOs (value objects) I ended up with was fairly large (about 10) as I was very careful to create granular VOs so that I had zero coupling with the underlying service layer which was hidden away by the Delegate classes. The underlying service layer certainly had its own VO like objects which I could have permitted to bubble up to the model/view, but taking the decoupled VO approach is the way to go in an MVC framework such as Cairngorm. You can end up replicating a lot of properties etc, but it is worth it in the long run as your VOs help you gel your domain model without tying it to the underlying implementation.
In the past I’ve played around with PureMVC, as well as my own custom MVC like framework for throwing together quick Flex apps. Overall I would say that my experience with Cairngorm in this small app was a positive one. There was a slight learning curve to get going, but it was not difficult at all if you have used other MVC frameworks in any other language. Cairngorm is heavily dependent upon Flex/AS3’s internal data binding and that can be a positive or negative depending on your personal views, however I found it to be quite powerful and convenient.
On the downside, the most awkward thing in Cairngorm for me was the Model (ModelLocator), for a small app like this one it was fine, but it just seems like a giant “global variable” store (not seems, it is in fact one) and if you are doing a complex app, I feel it would be necessary to break this up into different model’s for different parts of the application. Ideally each view should not be directly bound to your custom ModelLocator as Cairngorm forces this which basically couples your view directly to a specific model implementation. Instead a DI approach might be better.
Thankfully this application did not have to use the ServiceLocator as I was using in-process services (not web-services or remoting). Why was I thankful? Well when I looked at the ServiceLocator the whole thing made me cringe! The documentation on how to use it as well as the source, plus the fact you declare an wire it up in MXML…. It just seemed like a combination of bad naming and bad implementation. Secondly, unless you are using the hardwired web-service, http object or remoting versions in that class, the ServiceLocator in Cairngorm appears to be useless out of the box without customization. You just can’t easily plop in your own services bound by an arbitrary key. Why don’t they support custom abstractions of a “service” beyond the default “remote” three provided in Flex? Why does a “service” have to be remote in Cairngorm? Why should it care?
Overall… like I said my experience was fairly positive and would use it again for a similar project. That said, I do have some issues with the framework. I also fundamentally don’t understand why this framework is the “de-facto” standard promoted by Adobe and seemingly viewed as required knowlege for any “real Flex/AS3 developer”. Shouldn’t knowing the principles of MVC be more of a requirement than simply the nuts and bolts of a specific framework implementation?
Next stop… I am going to try out some other AS3/Flex MVC frameworks. I’ll report back on those.