Cairngorm vs. Joe Berkovitz’s MVCS

Skip Intro

You can’t go too long talking about Flex without also talking about Cairngorm. Cairngorm is a micro-architecture and lightweight, yet prescriptive framework. In English, it’s a set of classes and conventions you use to make large applications in Flex. It’s usually the main framework most bigger companies use when doing Flex work. I say most loosely because there is always the possibility of the loudest minority syndrome. While it may be lightweight, it certainly expects a lot of developer foreknowledge & experience at the get go.

Cairngorm is meant for large teams working on large projects. Does that exclude it from small teams and small projects? No. Is it worth it? Depends on the scope of your project and less so on the amount of people on your team. There is nothing inherently wrong with 1 person coding Cairngorm as far as I’m concerned. It is made with the multi-developer project in mind and is suited for 1 person as well. However, if you are working on disposable software such as a demo, prototype, informal test case, or even a simple form, to me it’s not appropriate. The Pragmatic Programmer has something they call Tracer Bullets, which can be dangerously similar to a demo; you are creating an app for upper management to see. The temptation is to use the demo as the product. This happens more often than people care to admit, so… when in doubt, use Cairngorm to CYA. Steven Webster, one of the creators, has his take as well as when to not use Cairngorm.

Getting back to the requirements, you have to appreciate OOP, mainly, the encapsulation aspect. OOP typically suggests to make your code black-box routines; you put something in and get a result out without knowing the details. One class shouldn’t know how another one works without following rules and patterns that justify it and keep it under control. If you don’t recognize the reasons behind encapsulation, Cairngorm won’t make much sense.

Secondly, Cairngorm uses a lot of design patterns. Design patterns are a series of engineering theories that have proven themselves useful and predictable in their application in the real-world. They’ve then been adopted to the software engineering world and have helped a lot. Some are built into the programming languages themselves, such as ActionScript, whereas others can be developed by the programmer; some can exist in both. The keyword here is they are theories, and like all scientific theory, they can be proven empirically true time and time again, but never become fact. In my opinion, if they did, the software industry wouldn’t be as f’d up as it is right now. If you don’t recognize the need for patterns, or find their usage in large numbers tedious, you won’t like Cairngorm nor understand it’s value.

Third, Cairngorm is a good, solid platform for a LOT of code. When I say a lot, mean Enterprise level projects where hundred of thousands to millions of lines of code are normal. A lot of rules breakdown at large numbers; Space-time inside a black hole for example and search algorithms with regard precision vs. recall. Google’s recall ability is what made it so successful [Ambient Findability]. If you aren’t going to write a lot of code (not vs. don’t plan to; 2 different things), and your application is extremely small in scale, you won’t like Cairngorm because writing a lot of the setup code for Cairngorm will feel repetitive and pointless; you’re writing flexibility you’ll never use.

Fourth, which goes along with the third point, Cairngorm is setup for large teams. I’m not really sure what RAD development means, but I do know it’s spoken in tandem by managers with “a bunch of developers working on the same thing at the same time”. Cairngorm facilitates this in that the various parts that make up your application can be worked on by different people. One or more can work on the View’s, others on the use cases via creating Events & Commands, and yet others on testing their back-end services via Business Delegates; or multiple people on different classes therein. In the early days of Flash development, I had a hell of a time figuring who could work on what, and when. On larger projects where you have more resources, it’s now easy to find a spot for someone to work in tandem with others on the team. Although I am not a big proponent of large teams, I still like Cairngorm. If you are the sole developer… well, you’ll just have more code to write than you already do. If you can’t open source what you are working on to get help, you may see Cairngorm as more effort than it’s worth since you are the only dev. This assumes of course you have your own methodology.

Cairngorm, in a nutshell, provides a nice Model View Controller framework solution for allowing mid-size to large teams to write code collaboratively, where the framework scales with the size of the project if used correctly.

So does Joe Berkovitz’s MVCS.

Now might be a good time to go read Joe’s article if some of the above points turned you off from Cairngorm. If they didn’t, cool, go read to see Joe’s somewhat simplified framework, and gain context for other solutions beyond the Cairngorm / ARP / Fast way of doing things. This blog post can wait longer than I can.

Done? Pimp! Notice any similarities? A lot, huh? This blog entry sounding like I’m writing leading prose? I’m honestly not trying to, but when I read Joe’s article, to me, I found an extreme amount of commonalities. Joe’s been doing this stuff for over 30 years. I’ve barely done 6. The difference between Joe and I beyond the experience difference, however, is that I fail to see how you can develop anything without Cairngorm that is an application. If it’s a demo / prototype, fine. If it’s a single form, fine. A widget, fine. A 2 month throwaway project or something strictly written for a presentation, fine.

…anything more? Why not start right from the beginning? Is it really that bad to dive right in?

Unfortunately, it’s not that cut and dry. While it’d be nice if everything were measured in 2 weeks, 2 months, and 2 years development cycles, they aren’t, and there is a ton of in between, hence the confusion on when to implement a framework like JB’s MVCS, Cairngorm, ARP, and/or others, parts of frameworks, etc as well as when to do so. A variety of facets go into determining these things, way beyond a developers reactions to the 4 Cairngorm expectations I listed up top.

If there is one thing I’ve learned my short stint in this industry, it’s that you never stop learning, and plateau’s are merely brief respites that are really temporary purgatories between your next large climb. Once you realize a new concept, you level up, assign your new skill points to various personal skills, and start heading for the next level. You then realize how much you really don’t know. Every time I go to a conference, I meet smart developers, and wonder how I even survive in this industry with so many smart engineers.

So, hopefully some of the following confusions & frustrations Joe and others can comment on and give context so I can learn yet more.

Before I rant (I already did?), I want to give context as to why I’m doing this. First, someone I respect said they respected Joe’s viewpoints in his article and really identify with them in terms of doing their real world development. After reading even just other bloggers’ comments that linked to the article, this kind of floored me because of previous expectations. Second, I’ve gone through blood, sweat, and tears to get to the understandings and appreciations I have now for various programming and design pattern concepts. For someone to offer an alternative approach who has a lot of clout… well, it certainly was a how did I get here moment. Third, Leif Wells wrote an entry going over Cairngorm, and some of the typical resistance you may run into. In describing the benefits, pro’s and con’s, it helped give me context to how team leaders view use of frameworks as well as Cairngorm’s public perception to others. His entry really made me think about if there truly is a line when it’s “too much”.

Let’s touch on the first 30,000ft view point of Joe’s article. All 9 pages have one common theme; respect of good programming practices. Frameworks cannot exist without these; if they do, you shouldn’t be using them. They say wisdom of crowds can also be the mob insanity. To me, decades of smart engineers all agreeing through various blogs, books, forums, and scholastic disciplines about programming concepts being valuable as well as being implemented into real-world languages is enough for me. Like Descartes, I trust collected history of human experiences, ecspecially engineers. The great thing about programmers is that they are quick to point out there is an exception to ever rule. Therefore, even though we can all agree Object Oriented Programming has done a lot of wonderful things for this industry… JSFL in Flash doesn’t have classes for a reason. Procedural programming has a lot of valid offerings. The key here is that programming concepts, once learned, are a lot like language. Once you learn Literature (English as it’s called here in the US), you then get your poetic license. You can break the rules when writing because you know why you are breaking the rule; you are breaking it with impunity, intent, and have a desired effect. The same for programming. It’s okay to violate encapsulation if you have a good reason for doing so. It’s okay to use convention in place of stringent language features.

Bottom line, to me, the crux of Joe’s article is that he espouses good programming practices. If you do too, inevitably your code will be good, and more easy to scale. Use what you need, leave out what you don’t.

Let’s look at the similarities. Cairngorm has a model, a view, and a controller. JB’s MVCS has a model, a view, a controller, and a service. Cairngorm has a ServiceLocator, but that is merely for getting a reference to the service via a string name, keeping in centralized in case you change a CFC’s name server-side, or your Java FrontController moves to another server. JB’s MVCS Service, then, is more like Cairngorm’s Business Delegate’s, Delegates for short. Both invoke “server-side stuff”. Both create asynchronous operations, like making an HTTP request, calling a web service, making a Flash Remoting call, or even reading a local config file. Delegates get the locations of these things from the ServiceLocator, but inevitably “knows what they are”, and creates them. My Flash Lite 2 project, these are just a LoadVars. In my work project with Flex 2 and Java, these are HTTPRequests; about the same thing. Flash asks the server for JSON; Flex asks the server for JSON. It could be an XML request, a WebService, whatever. To me, these could be perceived as Operations. JB’s Services create Operations that make calls to the server as well. Both get and parse the data.

Key point here, namely page 5 of 9, last paragraph. He makes a good point about the client side ValueObject’s (which both frameworks have), specifically, about optimizing client-side versions. I agree. One of the most challenging things I find in some of these database driven projects is mediating the lingo between me and the server-side developer. Sometimes, a project can go on for so long, I become unfamiliar with all of the back-end database table names, and DAO objects. Sometimes, the server-side dude’s expectations are of me that the client should match the back-end. This is idealistic, and unwieldy. I’ll usually “translate” back-end business-logic-translated-for-the-back-end-developers-desire-to-have-a-relational-data-scheme to something more reader friendly on the front end. Yes, we both have PersonVO’s with an ID, firstName, and lastName properties. But things like PersonPatientCrossRefVO’s, and various other meshes of value objects that are either base classes, representing a database has-a table basically, or just some back-end concept that has absolutely no relevance to my front end GUI, but has some ID I need to get data… I have to handle these things. You might not want to take a shower and wear a suit, by you do so to the interview to get a job. So, while the panacea for years for me was to have my server-side and client side ValueObjects be the exact same… this was doomed to never happen. Some stuff on the server I don’t need to know about… just enough to get an ID I need to “barter” with them to give me the data I need. The same holds true for me. A lot of my optimized VO’s, or neat Collections have nothing to do with the back-end, and are merely there to make it easier for me to make a good looking, responsive, and easily maintainable GUI that works well with data. Optimized bindings, organized lists, etc. In my blind rush to get everything to match, I learned that Remoting, in the end, was merely a more efficient client to server communication technology. It took a large project for me to see my folly. Smaller projects? Maybe still valid.

It also implies, too, that Factories won’t go away. Neither Cairngorm, nor JB’s MVCS technically have the Factory pattern, but I use it in every single project I do now. Typically this is “throw some XML in, get a ValueObject out”, or JSON, and vice-versa. These are used in Cairngorm’s Delegates, or JB’s MVCS Services. Having a Factory create a nice client side version of our VO’s is very useful, encapsulated, and you end up with easier to read Delegate / Service classes.

I disagree with page 8 of 9 where it talks about Service objects passing data to the View. View’s should get their data in 2 ways; either through binding to a ModelLocator, or better yet, passed in via a parent. Joe does write about this. However, a View knowing status of a service operation is a valid need. I’ve written my own Cairngorm modifications just to facilitate this. My way was invented when I brainstormed with my team (Nahuel Foronda, Tom Link, and John Yanarella). A View has a callback it passes into the event it emits for Commands. These Commands then call these callbacks when they are “done”. It passes back Callbacks, which are like events, but are strictly there for context since I personally was uncomfortable with the idea of the same Event class playing double-duty. Either way, in Cairngorm, setting Model data is it’s sole duty. There is a reason for this: You’re back-end can change from XML to JSON, and your Commands don’t change. In JB’s MVCS, you’d have to change the same services class.

Is this bad? With few developers, no. Changing 1 class, or 1 bigger class is the same to me; just quicker to do the former via scanning. In a team environment, that won’t, fly, though. It’s pretty easy for me to have a Delegate in Cairngorm throw back a fake JSON object, and the rest of my team can continue working, even with the use cases (Commands). Additionally, while Command classes become significantly easier to read, for smaller projects, you’ll quickly wonder why you are writing 40 lines of code in a new class file that effectively do only 1 thing: set some data on the ModelLocator.

JB’s MVCS has the nice benefit here of a View knowing the “status” of a call. In Cairngorm, your default knowledge is “I emit an event, and go about my business”. Usually, Flex devs will set their RemoteObject calls to show the busy cursor. So, Flex apps work a lot like web apps in that a background process goes off and the user can continue working. A lot of times, this can be dangerous. If the user clicks save on the form, and assumes the data truly is saved, closes their browser and leaves, that’s a bad thing. You need to give confirmation, and other times, you don’t need confirmation, but you need to lock the GUI. There are various non-Cairngorm ways of remedying this challenge. State variables in ModelLocator that the Command can set or my callback approach are two. JB’s MVCS doesn’t have this problem. The Service can set all kinds of variables in the Controller which the View can access and/or bind to to know the “status”. To me, that’s a nice way to say “state variables”. In the end, your View is not built to a VO, but a few state variables in the Controller. I hate state variables. They are a bitch to manage on larger projects. Regardless, so far, my Event callbacks at least allow my View to know when things are “done”. I cannot for example show a progress bar for uploading a file easily without breaking the spirit of Cairngorm, whereas in JB’s MVCS, it’s easy and legit.

If you look at the first bullet on page 8 of 9 about the Controller having functions that a View can call being a lot easier than dispatching Events to run Commands in Cairngorm, he doesn’t say Cairngorm, but he implies it. Yes, it’s a pain in the neck. By why is it better? Parameter order. A function in ActionScript 3 has a strict order of parameters. These cannot change. If they do, you need to change all View’s that use the functions. Parameter View typically changes for the same reasons you’d need to change a property on an event. So, this is a mild benefit here that shouldn’t be underestimated.

It is kind of frustrating, though, managing Event classes in Cairngorm. Some Events have nothing to do with Cairngorm, like Now, luckily, that’s intrinsic. But, your custom ones need to reside somewhere in your folder structure either in the same package as the Cairngorm ones, or not. I vote for not, but some people like re-use of Event classes.

On page 9, he hits the interfaces questions, which are really good gut feeling metrics which I really agree with. Another really simple one to add: If others are going to use your code after you, use an interface. That way, they can’t whine about your inheritance tree, only your method requirements which is way more subjective. The fact that they can, by rules, play in your code with their code is much better than having to extend your code to play in your code.

That’s why Cairngorm 2.0 to 2.1 was half a PR move; it made all the Cairngorm hackers like me happy! I could use my own modifications, and yet still be officially using Cairngorm 2.1 on a project.

Additionally, on Singleton metrics, his first bullet point about asking yourself “could there ever be more than one of these, in this project’s lifetime?”. The exact same argument should be used for bindings vs. public getter / setters. Joe mentions this too, about having a parent set data on the child vs. having the child bind. It might not be apparent why you’d do this when binding is great. Beyond Joe’s reasons, debugging bindings is the most painful experience since a lot goes on under the hood when data changes. It’s easier to put debugging statements inside setter functions to recognize what really is getting set, and by whom. It also makes your View’s, like Joe says, flexible.

So, as you can see, Cairngorm and JB’s MVCS have a lot in common. A lot of Joe’s concepts are heavily based on good programming practices. I’m not going to say that Cairngorm allows you to be a dumb programmer, but following the rules, you can have a variety of skill sets on a project, and still be very productive getting real, useful code out of the team. The Delegate code, for example, could be nasty, but at least it gives the data to the Command correctly, and later can be re-factored. I suppose one could use the same argument about a Service object, but again, they do 3 things, not 2, (get data, parse data, set model) thus open the doors for more trouble.

To recap the similarities & differences, both have View’s, and agree that View’s should bind to a global Model of some sort, typically a Singleton using Flex’ built in data-binding. Cairngorm doesn’t explicitly state it, but having parents set data on View’s is more reusable like Joe says, for both. Both have a global singleton Model class of some sort. Both advocate making more than one if the class gets too big. Both respect the MVC approach of having View’s ask the Controller to change data on the Model, even though they have a reference to the Model to display data in it. JB’s MVCS has a Controller to do “stuff”. Cairngorm’s is done in Command classes, JB’s MVCS in the Controller class. I still haven’t figured out how you make the Controller class scale as opposed to Cairngorm Commands; when I used the Controller class in Flash, that thing got huge after awhile (aka a bunch of functions on _root). Cairngorm Commands set data on the Model and Business Delegates to get the data and parse it back for the Command which makes them. In JB’s MVCS, Services create Operations which do all 3, and can return that data directly to the View. Cairngorm does not have a standard way of doing this; it assumes that Views’ binding to a piece of data on the ModelLocator will have their data-bindings fired, which does work. Calling the Controller in JB’s MVCS is easy; you call a method on the Controller singleton class. In Cairngorm, you make an Event and dispatch it via the CairngormEventDispatcher singleton class. Neither proposes “return values”.

Hopefully reading Joe’s article will do a few things. First, it should give you an understanding that regardless of what framework you look at, good programming practices are paramount. Second, there are simpler frameworks than Cairngorm. Third, you can understand more about Cairngorm now that you have something to compare it against.

Me personally? I’m sticking with Cairngorm. I don’t see how the Controller in JB’s MVCS can scale, I don’t like being tied to parameter order in Controller functions, and I dislike the triple duty Service objects have after learning time and time again the benefit of using Delgates as a shield to changing middle-tier requirements. Regardless, if someone was using either framework on a project, I’d immediately know “how the app was built” which is something that shouldn’t be underestimated. There is nothing cooler going to a random client who needs Flex 2 help with an existing app, and they go “We used Cairngorm”. I immediately know how the app is built and can dive right in assuming they implemented Cairngorm correctly which is hard to screw up if you read the docs or hit up Flexcoders to ask if you are on the right track (or blog it).

15 Replies to “Cairngorm vs. Joe Berkovitz’s MVCS”

  1. Hey Jesse,
    Check this link out Cairngen . My friend and fellow Flex Coder Eric Feminella wrote a code Generator for Cairngorm. It will Create a Cairngorm project structure for you and Sequencing within the prj after that. This really takes the ctrl-c .. ctrl-v out of developing Flex based apps which utilize Cairngorm. We have been using it since he created a few months ago and it is a real time saver and enforces Cairngorm Best Practices. Hope it helps,
    -Augie Marcello III

  2. What i like about Joe’s architecture is the Controller. In fact, if we talk about the simplest thing that could possibly work, calling a function on the Controller looks much simpler to me than creating an event and dispatching it.

  3. Heck yeah it is. My problem with that, though, is on larger projects. For example, on a current Flex 2 project, we have 35 commands. The average size of each command is about 100 lines, mostly passing the required data to the server via Delegates, and putting returned data on the model.

    Putting that in a single file would amount to at least 2000 lines of controller code removing out the redundant imports and execute functions. Still, it’d be a beast of a class to manage. This is a small Flex project so I can’t really see how I’d keep the controller class clean without making multiple controllers, which brings up the problem of how do you associate which controller to which actions?

  4. We could still create commands and call its execute method inside the controller method if necessary.

  5. I saw Joe’s presentation at Max and actually looked at his architecture before venturing down the Cairngorm road. What makes me satisfied with Cairngorm is that out-of-the box feeling. It has documentation and an entire community behind it (flexcoders), not to mention it makes me look like I can program like a demon.

    – mr

  6. People often dismiss Cairngorm as a solution for small/medium size projects due to the coding overheads. Sure, if you are coding everything by hand, Cairngorm is overkill on smaller projects, but most of this grunt work in a cairngorm application can be automated through ant tasks.

    At massive we use a slightly modified cairngorm framework for almost all our AS2 flash projects. Initially we were only using cairngorm for larger applications, now that we have a library of ant tasks that do most of the grunt work for us, we have found that cairngorm is great for smaller projects as well.

    We have built up a range of reusable ant tasks that we use across projects. Primarily we use a task that can generate an entire stub flash/cairngorm application through a few simple parameters (package name, swf name, flash version, etc). We also have a set of tasks for generating stub code/classes in multiple locations – such as creating a new command and delegate along with all the references required in the controller/serviceLocator/etc.

    This automation is great on projects of any size as it encourages consistency across projects and developers. It also saves time and removes repetition – the initial set up of a project that could take hours now only takes seconds.

    It makes the answer to the

  7. Can you recommend a framework I should check out for developing small to mid scale Flex apps? I typically code on my own and work 1 to 2 weeks on a project on average. I now bake my own (and probably flawed) MVC rip-offs. I’ve used ARP with Flex in the past but I don’t think it’s much ‘lighter’ than Cairngorm.
    MVCS may be exactly what I need: less overhead when compared to Cairngorm yet enough best practices to give me a cosy feeling :-)
    Any alternatives I should check out? We’re all starting out with Flex now (and soon Apollo) so why not learn things the right way this time?

  8. JB’s MVCS. ModelLocator is pretty universal. A main class that isn’t a View for the Controller is good for a bunch of app functions. A back-end won’t change in a 2 week project, so Services & Operations with their shared duties is great.

  9. Sorry, just had my first cup of coffee. I disagree with the Services & Operations for the smaller project. While I agree the Controller still should be on the one setting the ModelLocator data, just shove the data access stuff in the controller, or maybe via 1 class. Some Services / Operations can be small, but don’t feel like you’re forced to use them. Some of my smaller projects didn’t have many server based communication so no point packaging them up into classes for such a short deadline.

  10. Great article.
    Just picking up on Cairngorm/flex and this was very helpful to see it compared to Joe’s MVC.

    I’m sure its in the works, but neither framework has really talked about best practices with the new mx:Modules. For example, does each module have its own model locator, its own services? How should the front controller learn about the module’s events/commands and register them. Any ideas or advice?

  11. If the module.swf is being loaded from the same domain (security sandbox), no, they should not embed the same Cairngorm classes. They can use them, you’ll just use the load externs trick where the compiler generates the classes the module uses, and then you then use that file as the compiler’s exclude, as shown here.

    So, you can still bind to the ModelLocator, but not actually have the ModelLocator compiled into the Module.swf.

    The tricky thing here, however, is the Event classes. Assuming your application has trust with the module, you have a few options.

    First, you could simply just use Modules for their GUI portions, meaning, the GUI code & controls that make it up are what is being ‘loaded later’, and thus taking advantage of modules in that it’s not loaded up front. Your Event classes to trigger Cairngorm Commands could be in the same externalized file, meaning the main application compiles the class in, and the Module will just use that one when it loads in.

    Second, you could only embed the Use cases (Events + Command classes) in the module. When it loads, it’ll have to register it’s Event’s with Commands to run in the Controller. While this is nice in that further classes are abstracted to the module, you have a danger of a module ‘leaving it’s mess’ when it leaves. This means, Garbage Collection may not collect everything, or even the module since some classes that reference it may still exist. This is dangerous, but if you watch your self, you can take most advantage of what Modules have to offer.

    Third option is to go with the contract concept (interfaces), and extend the main ones they give you with talking to modules. You basically write an interface that ‘knows’ about Cairngorm stuff, and the Module has the same thing. When the Module is loaded, it tells the shell application the Events & Commands it would like to register. When the Module is unloaded, this contract ensures that the Module ‘checks out’. Remember the Blue’s Brothers, when Jake leaves prison and get’s his personal possessions on the way out, each being checked on a form all formal? It’s the same process with modules. If they are ‘Cairngorm Modules’, they will have the same interface the shell has, and both can ‘check in classes’ and ‘check out classes’ to ensure the Garbage Collector can do his job. When you get here, check your coat at the door. When you leave, don’t forget your coat.

    Fourth option is do #3, but have Modules know nothing about Cairngorm. Instead, they just emit events, similar to how a Button emits a click event. The Module loader, or whatever class is loading in the modules, is responsible for running Cairngorm events via the CairngormEventDispatcher. That way, Modules have nothing to do with Cairngorm. This is kind of hard, though, because as your Modules increase in scope, you’ll start to want a framework. Fine line.

    Fifth option is to use #4, but allow ModelLocator to be used by the Module for data-binding purposes. An OOP purist would stick to #4, though.

    Me? I’d use #3 and #4. Convention & contracts rock the mic.

  12. Hi Jesse,

    I have seen ur article and ur comment on using ModuleLocator in Cairngorm Framework … and it is really fantastic.

    Actually I’m too working on the same approach for my application development. But I have been struck with a problem that is, not able to load the Module in a ModuleLoader through this approach.

    In my application I have the following files:

    1) CheckLogin.mxml – Main Application Mxml contains the Services, Front Controller and a script (AppStarter)

    2) – It is the actionscript which extends the container to create the ModuleLoader to load the default LoginModule

    3) – It is for defining the loginevent generated by the Login Button.

    4) – It is for the executing after the event had fired, here I have called the Appstarter to load the Thanksmodule in the ModularLoader.

    My application loads the Default Module (Login Module) properly and on submitting the event it fires properly and dispatches it to the Login Command, the Command also executes the method in the AppStarter for loading the Module in the ModuleLoader, here in this area I didn’t find any response at all. It doesn’t load the New Module I have specified to load in the Loader.

Comments are closed.