IResponder and Cairngorm

Friday, November 23rd, 2007

My original post on Cairngorm and IResponder had accidentally been deleted while updating my moderations queue, and many of you have contacted me stating that the post is no longer available so I will re-iterate what I mentioned in that post.

For some time now I have been entertaining the notion of abstracting IResponder implementations from Command classes into separate, discreet classes which are intended to handle asynchronous service invocation responses. There has been some talk in the Cairngorm community recently regarding Cairngorm Commands and IResponder implementations so I thought I would share my thoughts on the subject.

Typically most Cairngorm Events are handled by an associated Command. The Command handles the Event by updating a model on the ModelLocator, and / or instantiating a Business Delegate to manage invoking a middle-tier service.

At this point one could argue that the Command has finished doing it’s job – handling the Event. Let’s clarify by taking a look at a formal definition of the Command Pattern:

“The Command pattern is a design pattern in which objects are used to represent actions. A command object encapsulates an action and its parameters.”

From this we can deduce (in the context of a Cairngorm Event) that the Event is the “action” and the Command is the object which encapsulates the handling of the Event (action). The actual handling of the Service response could be considered a separate concern which is outside of the direct concern of the Event and Command, thus requiring an additional object to handle the service response.

However for many developers it is (by design) typical to simply have the Command implement IResponder and also handle the response from the service in addition to the actual Event. This makes sense from a convenience perspective, but not necessarily from a design perspective.

What I have been experimenting with is pretty simple and straightforward. It involves having a completely separate object implement IResponder and handle the service response directly.

Consider the following example in which a specific use-case requires an account log in (could the Login Example have replaced Hello World?). The following classes would be required: LoginEvent, LoginCommand, LoginResponder and LoginDelegate. Utilizing a separate class as the responder is very simple and straightforward and would be implemented as follows:

So far nothing different here, the above Event is just like any other CairngormEvent. Now let’s take a look at the Command implementation.

Based on the above example, the only method which must be implemented is execute(), as defined by ICommand. The implementation of execute() instantiates an instance of LoginResponder and LoginDelegate, the LoginResponder instance is passed to the LoginDelegate as the IResponder instance (as opposed to the traditional approach of the Command being passed).

As can be seen in the following example, the Business Delegate implementation is the same as any other typical Cairngorm Delegate:

The IResponder implementation would be as follows:

That’s pretty much it. Clean, simple, and yes, more code, however this design supports a clear separation of concerns and promotes encapsulation and code reusability. This example is intentionally cut and dry, however if you consider the many other possible implementations such as utilizing Dependency Injection to inject both delegates and responders, than I believe the benefits become quite clear.

At the end of the day it really comes down to personal preference. For me, I always prefer to have more classes which encapsulate very specific concerns and responsibilities. As long as you have a clear and concise, but most of all, consistent design you usually can’t go wrong.

{ 9 comments to read ... please submit one more! }

  1. Thanks Eric. Great explanation. At times I’ve had both my Command and Delegate classes implementing IResponder ( see http://nwebb.co.uk/blog/?p=118 ) – any ‘heavy lifting’ was done in the Delegate’s result method (to keep the Command class as clean as possible) and then the simplified result was passed back to the Command. However, I prefer the idea of having a separate Responder class which takes care of everything. It can be used to achieve the same thing but in a cleaner way, and I guess that if the Command needs to respond to the async operation in more than one way, a simple responder factory could be implemented and the intention would be very clear.

    You don’t show the Delegate in your post but I assume there’s nothing unusual going on. Are you just setting token.addResponder(responderRef); ?
    Cheers, Neil

  2. Hey Neil,

    Thanks for your comments. I didn’t include the delegate in the example as it is not really needed to illustrate the implementation of a separate Responder.

    Thanks,
    Eric

  3. Hi Eric,
    I think the way you decouple the command from responding to the service is great, yet, I haven’t found any good approach to do the same thing with when I want to chain commands.
    With the SequenceCommand or event chain I can do it quite easily but what would be your approach to such situation where a command needs to be executed right after the responder parsed the data ?

    Thanks,
    Almog Kurtser.

  4. Hey Almog,

    Invoking another Command from a Responders result would be very easy to implement as all that would be needed would be to pass a reference of the Command to the Responder instance via its Constructor

  5. Great Idea!!! Favoring composition over inheritance… Great Design…
    I’ve been using Cairngorm with mid-size project and its helping me a lot…
    Just wondering… can I use Cairngorm Events (and Commands) to handle View Behaviors (loading components, displaying modal forms, etc) or should I use customized events for that…? Thank you

  6. Hey Ivaramme,

    You certainly can use Cairngorm Events and Commands to handle view specific behaviors. Any application level Events should be implemented as higher level Cairngorm Events. So as a rule of thumb, if you are building an application with Cairngorm all application specific Events should be implemented as Cairngorm Events. All low level events should be implemented as generic Events. For instance, if a component needs to communicate with another component, but the interaction only pertains to the components, not the higher level application as a whole, then the Event should just be a generic flash.events.Event and not a Cairngorm Event.

    Hope that helps.
    – Eric

  7. Sure!!! Thank you very much… it was in existential doubt… 🙂
    Thank you

  8. Hey Eric,

    This is very interesting.
    What I’ve noticed when using the profiler is that commands that do not implement IResponder get cleaned up by GC.
    However commands that use delegates do not.
    It seems it may be because of the front controller. Front controller uses weak references but perhaps because the command is used as the responder in the delegates call object, the FrontController never releases it.
    If the FrontController is removed these instances are cleaned up.

    I was wondering.
    If we use Responder objects instead of commands, perhaps after the responders.result() finishes we can remove the reference from the command to the responder there for freeing up the command for gc and hopefully leave a circular reference for the responder and delegate so that they can also be cleaned up.

    I will test this later.

    Hope my ramblings made sense.

  9. Hey Bjorn,

    Utilizing separate Responder objects will reduce an applications memory footprint as the Command will immediately become eligible for Garbage Collection in the next sweep once the Commands execute(); implementation returns.

    Let me explain. When a Command implements IResponder and instantiates a Business Delegate there is a reference to the command via the delegate and the AsyncToken instance, thus the reference count for the Command is greater than 0 and it will not be deallocated. The Command will only be eligible for garbage collection once the AsyncToken invokes result or fault on the Command and the flow of control is returned.

    When using separate Responder objects the memory allocated by the Responder instance will almost always be more efficient as the extra overhead associated in the execute implementation of the Command is not be a part of the Responder.

    Hope that clarifies some things.
    – Eric

{ 0 Pingbacks/Trackbacks }