Now that you have isolated two specific elements of the Cairngorm Micro-Architecture, you will now create a more complete Cairngorm application. Up to now the tutorials have covered only one design pattern, the ModelLocator, but now you will be introduced to the most crucial element of Cairngorm, the Service to Worker design pattern. The explanation of this pattern will span two tutorials. This tutorial will cover the basic flow inside of a Cairngorm application, and the next tutorial will expand this flow to include server interaction. However, before you can properly implement this design pattern you need to learn about the organization of a Cairngorm project.
Organizing a Cairngorm Project
One of the tasks involved with any project is organization. When working with other developers, this becomes extremely important. Normally a Cairngorm project is organized in the following manner:
By following this standard, you can know where to find any class that you may need in your Cairngorm application. Figure 1 illustrates this project structure. It also is a good development process to have a standard organizational structure for your projects - even if you are not using Cairngorm.

Figure 1 - Cairngorm Project Structure
The Service to Worker Pattern
The Service to Worker pattern is the hardest for most people to grasp. It encompasses most of the logic for a Cairngorm application. To understand this pattern, you will need to understand some of the classes that are included with Cairngorm and their respective purposes.
The Cairngorm Event Flow
The way that these classes interact is the Cairngorm Event Flow. Figure 2 illustrates this entire process. While this process seems lengthy, it follows a logical order.

Figure 2 - Cairngorm Basic Event Flow
For example, assume that Figure 2 shows what happens when a user clicks a login button. It would follow the following steps:
Once these items are understood, the next most important thing to understand about Cairngorm is: Everything Should Be Mapped to an Event. This is a drastic over-simplification, but it holds true in most situations. When a user clicks a login button - it should dispatch a CairngormEvent. When the user selects an option to change the view - it should dispatch a CairngormEvent. When a user submits a form to be stored on in a database - the form should dispatch a CairngormEvent. The dispatching of a CairngormEvent sets everything in motion.
Custom CairngormEvents
The class CairngormEvent can be used inside of your project, but in most situations you will create your own custom events that extend CairngormEvent (as stated previously, for an event to be included in the Cairngorm Event Flow it should extend CairngormEvent). Another reason to create custom events it to create custom properties of the event which contain data that you need to pass to the command. CairngormEvent has a property named data (of type Object) that can contain data, but it is ideal to have a strongly-typed property where you can place the data to pass.
For this example you will create an event that corresponds to the earlier example of a login page. This event will need to meet the following criteria:
Code Example 1 illustrates this completed event. You can see that you will need to import both CairngormEvent and the basic Event class. Also, as with all events, you have to define the Event constant. In this instance, you can use LOGIN. The properties are defined below the constant - and they also are passed into the constructor. The only thing out of the ordinary is that you need to override the public method clone(). This is the the method that the event uses to make a copy of itself. This is key in the Cairngorm Event Flow. Also, for the function to implement ICommand this method will need to have a return type of Event (and not CairngormEvent).
Code Example 1 - Custom Event
Commands
The Commands within a Cairngorm application actually "command" the application. Even in the next tutorial where you will be interacting with a server, the command still will do a majority of the work. In this example you will create a component that will receive the username and password from the LoginEvent, check the values against hard-coded values, and then change the workflowState on the ModelLocator if the values are correct. The following example performs these steps (but it doesn't have the hard-coded values included - that will be covered in the video).
The first thing to notice about the code below in Code Example 2 is that the LoginCommand implements ICommand. To accomplish this the ICommand class is also imported. In addition, you will notice the boilerplate code that you have used in the past to bring in the ModelLocator. To properly implement ICommand, the method execute() is also created. It received an event of type CairngormEvent (it has to be CairngormEvent and not LoginEvent to properly implement ICommand). To properly use the event, you will need to cast this event to the type LoginEvent (the process of casting will be further explained in the video). The actual logic has been left out of this command, but you can see that the ModelLocator updates the view. Once the logic is implemented this line of code would probably be inside of an if statement.
Code Example 2 - Cairngorm Command
Front Controller
As stated earlier, the FrontController maps your CairngormEvents to specific commands. Without this, your events would never integrate into the Cairngorm flow. The class extends FrontController and has two methods: the constructor and the initialize method. The initialize method is where you will use the addCommand method to map your events to commands (as you can see with the LoginEvent and LoginCommand).
Code Example 3 - The Cairngorm FrontController
Simply creating a FrontController is not enough. Like any class it needs to be instantiated inside of your application. Code Example 4 illustrates how to instantiate your FrontController in the Main.mxml file of your application. You simply need to add the control directory as an XML Namespace and then include the FrontController tag in the file.
Code Example 4 - Integrating a FrontController
Now that you have seen the basic elements of a Cairngorm project, you can actually build the working sample with the video. As always, the application code is included below.
Application Code
Download (7 Kb)
Looking Ahead
This is the basic Cairngorm flow. You may notice that this flow really does not include any "Services" yet. Server interaction will introduce a few additional steps to the flow (which will be covered in depth in the next tutorial).
Hi David,
In code sample #1, I’d recommend putting the additional properties inside the “data” object which is defined in ICommand:execute() [http://www.davidtucker.net/docs/cairngorm/com/adobe/cairngorm/control/CairngormEvent.html#data]
Also, it might be better practice to pass in a loginVO to the LoginEvent() constructor rather than individual properties. The idea being that the loginVO would get sent to the back-end service.
Excellent articles. Looking forward to the next one!
It should go in a VO, but I didn’t want to dive into VO’s until the next tutorial (this tutorial ended up being a bit longer than originally intended). In the next tutorial, I will cover VO’s and the ServiceLocator.
Thanks again for great tutorial!
Just perfect! Thanks
Excellent. Thanks a million for these tuts, very helpful! When is part 4 coming?
I estimate that Part 4 will be published this weekend. I wish I could have it done sooner, but I try to be sure they are as thorough and error free as possible.
These tutorials are fantastic David, they are helping me dig into Flex more than anything else I’ve been able to find out there so far, keep ‘em coming!
It is very helpful for me .Hope to see next one soon.Thanks.
[...] basic Cairngorm Event Flow that is handled in Part 3 is essential to any Cairngorm application, but most applications interact with a server. The [...]
David,
While I was waiting for part 3 I looked into PureMVC as well. Seems to be a lot of similar concepts between the two frameworks. PureMVC has a lot of talk around it right now – any experience or insight into how it compares to Cairngorm? Cairngorm is backed by Adobe, but PureMVC seems to be a little bit more straight forward and a little easier to grasp. Again, finding your tuturials the best material on Cairngorm yet.
@Flex New Guy – PureMVC is certainly getting a lot of buzz. I have briefly looked into it, and I am still evaluating it for enterprise-level solutions.
I do have one note though – if you are a professional Flex developer, you need to know Cairngorm. It was the framework that Adobe supported, so many companies still rely on Cairngorm (and will continue to – even if “easier” frameworks come along).
[...] Part 3 [...]
[...] http://www.davidtucker.net/2007/10/29/cairngorm-part-3/ [...]
thank very much
Thanks
[...] Tradução do original inglês: http://www.davidtucker.net [...]
This is completley irrelevant, but I really wish this was named something other than “Cairngorm”. What a lousy name. Not slick, doesn’t roll off the toungue, and just conjurs up a picture of something completely hopeless, much like a hurricane hitting the Gulf coast.
Thanks for taking the time to do these tutorials. Some things are finally starting to “click” regarding Cairngorm.
Great tutorial… however as soon as I instantiate the controller in the program, either the way you do or with AS3, the application fails to build silently. very puzzling! I’m using latest SDK with FlashDevelop, same problem with Flex builder 3. The code is downloaded from this page. Please help me!
Excellent tutorials !
I read several articles to understant “Service to Worker” pattern,
this article helped me a lot understand it!
Thank’s again !!!
[...] David Tucker – Web Development Goodness » Blog Archive » Getting Started with Cairngorm – Part 3 Looking for some examples of how people break up flex directory structure (tags: cairngorm flex) [...]
great tut thanks
Great tutorial, thank you so much.
I was wondering how to structure my cairngorm directories for things I resuse in multiple applications, such as the login/logout screens.
Thanks,
Shannon
very thanks
public class SampleController extends FrontController {
public function SampleController() {
this.initialize();
}
public function initialize():void {
//ADD COMMANDS
this.addCommand(LoginEvent.LOGIN,LoginCommand);
}
}
}
according to your codes of LoginEvent class,LoginEvent.LOGIN==”Login” which is a String value.
so we can see that code “this.addCommand(LoginEvent.LOGIN,LoginCommand)” just map the LoginCommand to a String value,rather than an event.
it confused me.
[...] Tucker :: Getting Started With Cairngorm :: Part 1 :: Part 2 :: Part 3 :: Part 4 :: Part [...]
Excellent.:):)
Hello,I come China.
Very Great tutorial.Thanks!
I wanna to learn more and more,so,please updata more and more tutorials.
: ) I’m glad come here.
This tutorial will help millions of developers who are into flex. Thank you so much for sharing this information. Cairngorm may be a bit hard to comprehend by just reading a book or information, the additional video tutorial really helped a lot. Now I’m beginning to see and understand the Cairngorm way.
Thanks so much! I just bought the Air 1.5 Cookbook, knowing the explanations would be understandable and complete. Just converted an application to Cairngorm and it may be my imagination but performance seems to have nearly doubled.
Thanks again
it’s really useful
Super tutorials. Thanks
Thanks for your hard work. Excellent and clear tutorials.
Thanks for all of your tutorials! I’m not sure where the best place to post this is, but I am wondering what the best way to handle multiple workflow states in Cairngorm. For example, the modelLocator dictates the workflowstate of my main views (8 of them). Within each view, there are views (e.g. each module will need to link to sub-modules. I initially got things working by creating another set of public static const(s) in the modelLocator, but when populating and XML tree and then attempting to link to the main modules and sub-modules, the workflow state numbers started to overlap, and the main workflow state would always trump the others. It almost seems like there needs to be separate modelLocators for each sub-module, but it seems like that is a no-no. What are your thoughts as the best way to handle it. To get an idea, in my modelLocator I have something like this:
public static const LOGIN_SCREEN:uint = 0;
public static const WELCOME_SCREEN:uint = 1;
public static const ADMIN_SCREEN:uint = 2;public static const ORDER_SCREEN:uint = 3;
public static const ORDERVIEW_DASHBOARD:uint = 0;
public static const ORDERVIEW_CHECKOUT:uint = 1;
(so, a separate viewstack has been instantiated for the submodule using the “ORDERVIEW_..” constants. Hopefully there is already a better way to handle this. Any advice?
Hi again, sorry I think figured it out – I just created different variables for the workflowstates (e.g. in the model locator set a mainflowState and an orderworkflowState) and that helped me manage the multiple nested view stacks.
very nice tutorial. I have seen many articles but none of them come any close to this.
Great
thank you
Wow, thank you for these excellent quality video tutorials!
I really appreciate your tutorial. Looking at different comprehensions I found yours to be simple enough to understand. Thanks.
@Newton – Thanks! I am glad that it was useful.
[...] Now that you have seen the basic elements of a Cairngorm project, you can actually build the working sample with the video. As always, the application code is included below. [...]
[...] basic Cairngorm Event Flow that is handled in Part 3 is essential to any Cairngorm application, but most applications interact with a server. The [...]
Hi David,
The videos are very useful & gave me a clear idea on MVC in Flex.
I have a doubt on “IModelLocator” interface, i tried not to implement any “IModelLocator” in program but results the same .I don’t see any difference(probably i might miss somethings) . Could you please give me a idea on the services provided with the same .
Thanks,
Kiran
Thank you very much David,
this is the first Cairngorm Tutorial which opens my eyes.
Go ahead
<3
dl
Goooooooooooood job David
I appreciate your work on this.
Looking forward to the next one!
Quick question. At the end of the tutotial, you map the click event for the login button like so:
click=”{login(event)}”
Do the curly braces serve any specific purpose when used in conjunction with in-line AS3 coding?
I’ve been trying to work with Cairngorm for a while…
This really clears things up! Thanks for all your hard work.
Hi David, I am following along in your tutorial videos, and I got stuck on tutorial 3. Example 1, LoginEvent.as is giving me an error in Eclipse Flex Builder: “1046:Type was not found or was not a compile-time constant: Event”. Which is strange because I certainly has import flash.events.Event;
in the code there. Is there something wrong with my Flex Builder class path configuration or something?
Thanks.
So, from reading this, it seems we are to only standardize the data objects coming FROM Flex to ColdFusion.
Result data returned from CF is sent to the command where the result ‘action’ takes place in the responder.
I.E. – My understanding is that the data returned from CF (Database) is used by the command and does not have a VO associated with it.. right?
[...] recordings). I have been following this excellent series of tutorials by David Tucker. On part 3, David goes through the complete architecture. I have been trying to wrap my head around the [...]
Hi David !
This is an amazing stuff on Caringorm/.. Thanks a lot man..
Need one more thing, how to manage different components in a single view..
Please help me out..