Cairngorm: One-to-One Events and Commands Doesn’t Make Sense

by Kyle Hayes on January 17th, 2008

I am struggling with a particular concept in Cairngorm. I don’t understand why it is considered best practice that your custom cairngorm events and commands are to have a one-to-one ratio. Flex itself is not even modeled this way. For example, when a button is clicked, you don’t listen for a class called ButtonClickEvent. Instead, you listen for the ButtonEvent.CLICK or ButtonEvent.DOWN or whatever the case is. In Cairngorm, how come you cannot do the same thing and list multiple event types in your event classes.

I am not suggesting to put all your types in one event class. But let’s say you have a UserEvent. You could call UserEvent.ADD_USER, UserEvent.DELETE_USER, UserEvent.LOGIN_USER, etc. That is all in one class instead of having three separate classes. Can someone please explain to me the reasoning for the one-to-one ratio please?

Thanks in advance!

Popular Posts

From Flex

15 Comments
  1. I’ve actually seen some sample Cairngorm projects that are built exactly as you are suggesting. As a matter of fact I’m doing my events that exact way because it ‘felt better’ to me. I think one pitfall of this method though would be in cases where the strings for the events were the same. For example a LIST.CHANGE and SCALE.CHANGE both with String values of change. For that I remember reading reccs to use the reverse package name for the string value like "com.domain.app.events.List.CHANGE" and "com.domain.app.events.Scale.CHANGE" to differentiate the two. I’d be curious to hear what other points of view are about this approach.

  2. @diamondtearz – While I was reading your posts about the duplicate event names, I was thinking about the reverse domain thing as well. I just read that about an hour ago. I have used the method that I described above in a recent project as well and it worked fine without issues. But, others were criticizing me saying it wasn’t right.

    You mentioned you have seen examples, as have I, but I can’t seem to find any of them, do you happen to know the ones you saw?

  3. Ok looks like this app has an example of what I am talking about:
    http://www.zeuslabs.us/demos/YahooCairngorm/srcview/index.html

  4. As far as I ever understood Cairngorm, the commands are meant to hold all of the logic pertaining to a specific area of the application, so you might have a UserCommand and UserEvent that has UserEvent.LOGIN and UserEvent.LOGOUT. In the execute, just switch(UserEvent(event).type) and deal with each independantly… but this way all of your logic for dealing with users is in one place.

  5. Well, that Yahoo app also has all the view code stuffed into one giant MXML file, so I’m not sure I’d rely on it for "best practices".

    I believe the idea is that most Cairngorm Events are very specific things. Obviously if you have two that are closely related, it might be OK to use the same Event class (but not the same Command class in my opinion). But with Cairngen, it is so easy to generate the boilerplate for the events, commands, and delegates that it doesn’t bother me too much just to keep them all in their own small, specific classes.

  6. I don’t have a problem with the code generation either. I am talking about just in general, what is the reasoning behind having the one-to-one. I agree with what you said about the Yahoo example, not the best one. I just want to know what the necessity is to have so many specific event classes?

  7. Yes, you could have UserEvent.ADD_USER, UserEvent.DELETE_USER etc as long as the event payload is then shared. That is, the member variables which hold the data for the event e.g. ‘user name’ are shared across all the event types encapsulated inside the single UserEvent. No problem there. Where things start to fall apart are when the different operations require a different event payload. You can’t have a single UserEvent and then stuff all the possible pieces of data into where some will be redundant depending on the ‘type’. This would be bad design and is probably the reason events and commands have a one to one relationship.

  8. I usually end up doing something like this:

    public class SomeEvent extends CairngormEvent
    {

    public static const ACTION_A:String = "ACTION_A";
    public static const ACTION_B:String = "ACTION_B";
    public static const ACTION_B:String = "ACTION_B";

    public function SomeEvent(…

    then call it this way
    var someEvent:SomeEvent = new SomeEvent( SomeEvent.ACTION_B, …

  9. Indeed. That is the way I have been doing it lately.

  10. Hey Kyle,

    I suppose you dont have to make it a one to one relationship. Just have one userevent with different types of user events and then in your command execute method run a switch statement to determine which event is being sent and do some logic. Now in that logic area is where will want to use classes as much as possible for reuse, you can also practice your design patterns here as well.

    Hope that helps , I started doing this at work recently and now my command folder isn’t as nearly as large.

    PS: first time posting on your blog via my iPhone ;)

  11. @josh – Hehe, about the iPhone…I feel special.

    In regards to the switch statements in your commands, I don’t know about that. The command pattern is meant to represent a single feature of the application. By adding in switch statements, it seems that you are bloating the patterns executable code. I don’t have a problem with the command folder being large, it was this one event for every command thing that I thought was not well thought out.

    Thanks for posting.

  12. Hey,
    Ya adding more code in your executable method in the command will bloat the command, but you will have fewer commands for sure, if you did it right it wouldnt bloat it that much… depends on how many different types of UserEvents you had (aka. Add_User, Delete_User, Modify_User, etc…)

    I dont think you can really get around the 1 to 1 relationship. Even if you do UserEvent.ADD_USER and you also have a UserEvent.DELETE_USER, in the UserEvent class each event will still need seperate commands b/c each one will need to call a different delegate method to run the backend (server) logic.

    You could get around the 1 to 1 logic by simply passing the event type to the delegate, which would call lets say a userService, and in that service it would call the correct ADD_USER CFC method to add a User based on the passed in event… likewise you could have a DELETE_USER cfc method that would delete the user if the delete event was passed in as a argument in the CFC… that make sense? It basically makes your delegate really small for Users, and lets you have one User command, one User event and puts all the switching in your CFC to figure out which cfc function to call based on the passed in user event. I thought about doing this once but never did it… figured I could live with a big command folder, one UserEvent, and my delegate just listed all my User Service methods.

    Also if you wanted to chain events this is a good post on how to do that:
    http://cairngormdocs.org/blog/?p=27

    Food for thought ;)

    Hows the new job? Ping me sometime lets chat.

  13. Hey Kyle,

    I use Cairngorm events structured like Flex events all time in my projects. I typically group them around a common value object or a common function. For instance to manage a user I would create a class called UserEvent. Within the UserEvent I would define the following events and also add a property to contain the ‘user’.

    public static const addUser:String = ‘ADD_USER’;
    public static const updateUser:String = ‘UPDATE_USER’;
    public static const deleteUser:String = ‘DELETE_USER’;

    public var user:UserVO;

    Now I have a single UserEvent that gets registered against three different commands in my FrontController, one for each respective use case in the event. Always have a separate command for each use case, those things should not get combined.

  14. Derrick, you just described exactly what I am talking about above. Thank you! I suppose to each their own right? If I want to do it this way, I should be able to!

    I completely agree about not combining commands. That takes away from the purpose of the command pattern in that each command should represent a single feature in the application.

  15. Jesse permalink

    This is possible and common in Cairngorm. See the Cairngorm Store sample application.

    The UpdateShoppingCartEvent uses multiple types which map to multiple commands in the controller. All of the other events are one-to-one.

    I typically use one-to-one, but when it makes sense I use one-to-multiple.

Leave a Reply

Note: XHTML is allowed. Your email address will never be published.

Subscribe to this comment feed via RSS