explorers' club

explorations in dev, science, sci-fi, games, and other fun stuff!

Tutorial: handling service validation errors & cairngorm – part 3

8 Comments

recap

Last time we discussed two methods for handling service validation errors in a Cairngorm application. The first method was to borrow from some AS2/ARP techniques by passing a reference. The second method was to leverage the event nature of Flex and use a central event dispatcher type approach. Both of these have their advantages and certainly have their disadvantages. This last approach will try to take the best from both worlds and combine them to alleviate some of the problems we encountered.

ServiceValidationErrorManager method

Again you will have to pardon the names here but this gets the point across. There is no doubt what this puppy does. For the sake of simplicity I will continue to call it “the manager”. Ok so the manager is a) a Singleton-type class and b) has at its root a property called currentClient. Here’s a peek:

pacakge com.foo.managers
{
     public class ServiceValidationErrorManager
     {
         public var currentClient:IServiceValidationClient;
         static private var _instance:ServiceValidationErrorManager;
         static public function getInstance (){}//you get the idea....
     }
}

The idea is pretty much the same as the first method in that our views serve as the IServiceValidationClient. When dispatching a Cairngorm event we register the client with the manager class (if applicable). Basically that is achieved by:

ServiceValidationErrorManager.getInstance().currentClient = this; //the view/implementor

So this fixes issues from the other two methods. Firstly it eliminates the need to pass the view to the command. Secondly it doesn’t get us tangled up in all these IEventDispatcher methods.

Now upon a response that has some validation errors, we can simply say:

ServiceValidationErrorManager.getInstance().currentClient.handleValidationErrors();

The other nice thing is that we needn’t really worry about garbage collection because we’re only dealing with one property on one class. It gets overwritten when needed. Now you may be asking why use a separate manager type class. Well you may want to have some logic in there for various things including queuing the views, and other crap I can’t think of right now.

summary

This could easily be adapted to a preexisting singleton model so you can reduce the need for the additional class. You just gotta remember its there. Also, even though you needn’t clear out the property on the manager, it does make good practice. Having a manager class allows you to do just that: manage validation errors appropriately. Of course this might be a grotesque oversimplification of a very serious need, you get the gist of the idea.

pros:

  • OOP
  • negates the use of IEventDispatcher logic in both view and command
  • provides a centralized place to handle more robust registration for error handling

cons:

  • adds another class
  • still doesn’t address timing issue, unless you implement some queuing mechanism in the manager when setting the current client
  • not as elegantly simple as method one

That’s it folks. 3 very ugly solutions to an ugly problem. Chime in and let me know how you do it. Thanks.

Advertisements

8 thoughts on “Tutorial: handling service validation errors & cairngorm – part 3

  1. Interesting reading. There doesn’t seem to be a definitive solution to this which I find interesting as it’s such a common problem.

    My solution – at the moment – is to have some sort of queue which is attached to the model where all database responses go into. I guess you could use a singleton manager class to manage the queue but I haven’t implemented this yet. All responders that respond to database interactions add an item to the queue and a custom event is dispatched with information such as the type of database operation, which view/component initiated it, operation success, message, errors, data (usually not necessary as the model has already been updated), id or token, etc., whatever is relevant to the app. In fact for all database interactions I nearly always use a GenericDTO that has all of these (relevant) properties. I send it to and from the server-side (where the relevant properties are updated) and then the responder adds it to the queue. It holds whatever VOs it needs in a property called data (which is an Array).

    The question I have about your methods is that I’m not sure why it’s necessary to register a current client, or even multiple current clients. Why not just dispatch a DatabaseResponseEvent like I’ve described above and any view that cares to listen can take action if it’s relevant to them. Maybe you have an application where multiple views should update themselves as a result of certain database operations? Who knows. If you enforce that all these views have to register themselves to a specific event, it could get tricky for no obvious benefit that I can see. Even if you only have one current client for each operation, I still think my approach works well but of course I’m biased šŸ˜‰

    I’m still trying to find the optimal method, as I’m sure you are too, so I’m interested to hear your thoughts on this.

  2. @Darren
    This may fluctuate from app to app but the reason I had implemented an interface is because for the most part, I feel that validation handling is the responsibility of the user and as such, the first point of contact is the view. Because our particular services were returning a standardized set of validation messages with their response, we are able to have all views handle this the same way.

    I kinda understand what you are doing with your approach though I am not fully comprehending the entire setup. But the big problem I have with using the events approach is that it requires quite a bit of extra work (remembering to do it I suppose?) for dispatching the event and setting up handlers. Now this may be simplified in your scenario, if so please hook us up with some code. The other issue I have with using the event-driven approach is now that we are having to setup listeners on the view itself, we then have to either do a check to see if the event has handlers here and/or remove the handlers when done. Otherwise if you dispatch a service command, you may start to build up repeated listeners which can cause a) timing issues, b) unwanted behavior and c) memory issues.

    I have no idea. None of the solutions thus far seem to be all that great. Though the more and more I look at the reference method, the more I like it, OOP or not.

  3. @Darren
    Can you upload some code so we can look at your example? Or do you have a blog posting that I might link to for reference? It would give people a fuller picture of the various solutions out there.

  4. I don’t have any code that isn’t buried deep in a Cairngorm project but I think I made it seem more complicated than it is. At it’s most basic – ignoring the queue manager class – just imagine an arraycollection in the model called databaseResponseQueue. All responders add a database response to this queue. All views that need to know about database interaction register an event listener on collectionchange on this arraycollection. Just once, in their initialization. Whenever an item is added to the queue, they have a look at the event and if they care about it, they take the appropriate action. Otherwise they ignore it.

    So there’s obviously some overhead as each view will examine each database response. However, it’s just one listener – out of potentially hundreds in a Cairngorm app – and it can determine in the first couple of lines of code of its eventhandler whether it’s concerned with a particular event or not. I also think that you definitely want a queue manager class to dispatch appropriate events, clean up orphan entries in the queue, that sort of thing, but the above scenario will do for the purposes of illustration.

    As I said, this has the advantage that multiple views can take action on the same response. Having thought about it, I actually can’t think of a practical example where this would be necessary as views will usually be listening for other changes to the model anyway. This doesn’t mean that there isn’t any practical examples but I guess it’s not that common.

    I guess my preference for this is more philosophical than anything. Flex is a very asynchronous environment. Most of the stuff that the Flex framework does is based on events – look at the component instantiation lifecycle for example. I consider views to be very transient, mutable things. For example, can you always be sure that the view will still be there when the database response gets back? What if the network’s congested and the database response takes a while getting back. Maybe the user hits cancel and moves onto a different view. What happens to the reference to the view (that may not exist anymore) when the repsonse does get back and the responder is called into action? Do you stop your app and wait? Do you always want to be concerned with stopping and waiting for every asynchronous event? I imagine views as being as decoupled as possible, sort of floating out there, dispatching request events to the real engine of the app and listening for response events coming back. It doesn’t really matter if they are there or not, or really what they can and can’t do. If the response event comes back and the view isn’t there, that’s no problem. If for some reason the controller needs the view to be there, you’ve tied to the controller to the view and you have to always be thinking about cleaning up after yourself, notifying the controller if the view is changed/removed, etc. With my method, you can destroy a view at any time and the app keeps working perfectly. Of course, this only applies to MVC frameworks like Cairngorm with single controllers. If I was using an MVC framework where every view has it’s own controller, I’d probably approach things differently.

    As I said, I’m no expert on MVC or OOP. Just thinking out loud really.

  5. @Darren
    Thanks for the clarification. You have brought up some good topics to address. Certainly the idea of a cancelable action initiated and subsequently canceled by the user before a service response has had time to complete poses some interesting issues for the referencing method.

    I plan to investigate an event-based approach a bit more with your points in mind. Thanks for that.

    You know, given so time do digest my 3 methods and this one you have proposed makes me think that at some point, someone should really establish some sort of defacto mini-framework for use within Cairngorm.

  6. I found these two links that deal with the same problem:

    http://www.thomasburleson.biz/2007/06/cairngorm_view_notifications.html
    http://www.dgrigg.com/post.cfm/04/12/2007/Cairngorm-Commands-Views-and-Harikiri

    The first link takes a similar approach to your “passing a reference” method and there’s now a Google code project based around it.

    I’m a bit more drawn to the second link though.

  7. I like see and collection optimizatotion competitions on the world.
    Give me links of rush, contest, experiment SEO … !

Leave a Reply

Fill in your details below or click an icon to log in:

WordPress.com Logo

You are commenting using your WordPress.com account. Log Out / Change )

Twitter picture

You are commenting using your Twitter account. Log Out / Change )

Facebook photo

You are commenting using your Facebook account. Log Out / Change )

Google+ photo

You are commenting using your Google+ account. Log Out / Change )

Connecting to %s