Check out our new training course on AngularJS for Flex Developers

Learning Cairngorm (Part 4)

I can't believe it has almost 8 months since my last installment in the Learning Cairngorm series. Life got in the way, and I have a lot of experience with Cairngorm now compared to when I wrote the first three parts. In the last part, I spoke a bit about getting the Cairngorm Store to work with ColdFusion. In this part, I'm going to switch back to Steve Webster's collection of Cairngorm articles and talk a bit more about some of the additional design patterns related to Cairngorm. I'll summarize Part 4 of Steven's Article and intersperse it with some of my own experience.

User Gestures have Changed

Applications have grown in complexity these days and there are many different ways that the user will need to interact with your application. Every opportunity that a user has to interact with your applications is a gesture. In the traditional HTML interface world, each gesture requires the loading of a new page. AJAX has changed this somewhat, and Flex has changed it a lot. Sorting a data grid or filtering a group of data can all be done without a round trip to the server? This is part of what leads to a rich experience for the user. A benefit of Cairngorm is that all gestures, whether or not a round trip to the server is needed, can be treated exactly the same. No matter what is going on, we have a standard set approach, and can use that to more easily debug potential problems.

Events, Commands, Controllers, oh my

First, we create a CairngormEvent class for each user gesture. The event class extends a CairngormEvent. It will contain a static variable with the name of the event. It can also contain instance variables, if those are needed to complete the event actions. This might be a sample CairngormEvent class:


package com.tempApp.event{
import flash.events.Event;
import com.adobe.cairngorm.control.CairngormEvent;

public class MyCustomEvent extends CairngormEvent{
public static var EVENT_ACTION : String = "actionname"

[Instance data here]

public function MyCustomEvent ([Instance data as arguments]){
[Set Instance Data Here]
super(EVENT_ACTION);
}

/**
* Override the inherited clone() method, but don't return any state.
*/

override public function clone() : Event{
return new MyCustomEvent ( );
}
}
}

This is a simple sample event class, but very powerful. The event class ties into a command class is the one that does the work. A command is a pattern which always has a single point of entry: an execute method. By creating a generic execute method on every command, the Cairngorm framework can generically run any command in response to an event. This might be a sample command class:


package com.tempApp.command{

import com.adobe.cairngorm.control.CairngormEvent;
import com.adobe.cairngorm.commands.ICommand;
import com.tempApp.event. MyCustomEvent

public class MyCustomCommand implements ICommand{


public function execute(event:CairngormEvent):void{
var e : MyCustomEvent = event as MyCustomEvent;
[Do stuff here]

}
}
}

When Cairngorm "sees" the Event, how does it know to relate it to a command class? A third class, a front controller, ties the two together:


package com.tempApp.control{
import com.adobe.cairngorm.control.FrontController;
import com.tempApp.event.*;
import com.tempApp.command.*;

public class AssemblerController extends FrontController{

public function AssemblerController(){
initialiseCommands();
}

public function initialiseCommands() : void{
addCommand(MyCustomEvent. EVENT_ACTION, MyCustomCommand );
}
}
}

I had one of those "hallway conversations" with some folks at 360Flex and a few people claim that a front controller has no place in a Cairngorm and is just overkill. I haven't had time to think about that, or look into alternatives to the approach, but I thought it'd be something worth throwing out there for those listening. If you have thoughts on this, comment and tell me why a controller has no place in Cairngorm.

Tying them all together

We have three elements at play, here:

  • Start with an event (AKA User Gesture).
  • The Event goes to a controller and figures out what command to execute.
  • Execute the Command

There are two missing bookends to our list list. First, what exactly does "Start with an event mean"? How do we tell the Cairngorm Framework or Flex that an event has taken place? Cairngorm has a special event dispatcher that tells the framework something happened that it needs to respond to. A sample line of code would be something like this:


import com.adobe.cairngorm.control.CairngormEventDispatcher;
import com.tempApp.event.MyCustomEvent;

CairngormEventDispatcher.getInstance().dispatchEvent( new MyCustomEvent ([optional arguments]) );

That is our first bookend. We dispatch our custom event, which looks at the controller, and executes the command. Holding up the stack, the command will then update the ModelLocator, which through the miracle of data binding will update relevant areas of the application. Our updated path list is like this:

  • Dispatch a custom event (AKA User Gesture).
  • The Event goes to a controller and figures out what command to execute.
  • Execute the Command
  • Command updates Model data, which updates the user views

Conclusions

This took a look at the architecture of a Cairngorm system events. We did not deal with retrieving data from a remote source, though. I'll look into that in the next part of the series. Now that I'm in a routine of blogging twice a week (Tuesday and Thursday morning) the next part of the series should come much quicker than this one.

Related Blog Entries

Comments (Comment Moderation is enabled. Your comment will not appear until approved.)
Tony's Gravatar I was wondering if you have taken a look at pureMVC? I am planning to make the jump on a new project. I think it looks like it would be worth the try. Here is a video of why people are looking at it real hard.
http://www.asserttrue.com/articles/2007/10/17/silv...
# Posted By Tony | 10/26/07 8:24 PM
Jeffry Houser's Gravatar In the very early days, I looked at PureMVC and decided against it because of lack of documentation. Based on the murmuring in the community this has obviously changed.
It is on my list of things to look at, but I have no idea when that'll happen.

I did sit through that presentation and was very surprised they said Cairngorm was well documented. :ha, ha:
# Posted By Jeffry Houser | 10/26/07 8:31 PM
Tony's Gravatar Time is always the issue. Doug McCune was right about the fact that Cairngorm is a must to know for the Flex consultant. Now that I have Cairngorm under my belt, I can afford to check out pureMVC. I would say 80% of my customers are using Cairngorm in their Flex apps. Of course, 50% are using it because I put it there.

You are right about the documentation on Cairngorm. That is why what you are doing here is so right on. My recommendation for any noob is to learn Cairngorm, if at all possible.
# Posted By Tony | 10/26/07 8:44 PM
Sean Moore's Gravatar Hey Jeffry,

This is a great article. I think this is one of the better explanations I have read for the FrontController, Events, Commands, Data Model, etc. I like how you are leaving the remote service access for the next part of this series too.

I am looking forward to Part 5.

Regards,

Sean
# Posted By Sean Moore | 10/28/07 7:41 PM
Jeffry Houser's Gravatar Sean,

Thanks for reading; I'm very glad you enjoyed.
# Posted By Jeffry Houser | 10/28/07 7:57 PM
David Tucker's Gravatar Great post (I too am doing a series on Cairngorm right now). Another great thing about Cairngorm 2.2 is that CairngormEvents can dispatch themselves with the "dispatch()" method. It just makes the code a bit cleaner.
# Posted By David Tucker | 10/29/07 7:28 AM
Jeffry Houser's Gravatar David,

Thanks for reading. I didn't know that 2.2 events could dispatch themselves. That is a real cool feature.
# Posted By Jeffry Houser | 10/29/07 10:30 AM
sergey's Gravatar Thanks for code, realy interesting
# Posted By sergey | 2/20/08 7:39 PM
Character Education's Gravatar nice explanation for front controller.
# Posted By Character Education | 3/20/09 5:50 AM
All Content Copyright 2005, 2006, 2007, 2008, 2009 Jeffry Houser. May not be reused without permission
BlogCFC was created by Raymond Camden. This blog is running version 5.9.2.002.