Barracuda DiscRack - Differences from the Traditional DiscRack
barracuda.gif (11456 bytes)Many people have asked "How does the Barracuda approach differ from the traditional DiscRack example?". This is the answer I gave to Dan Rosner recently when he asked this question...

Hi Dan!

> This looks interesting, since I've worked with the old
> DiscRack example included in the EE4 alpha. For the benefit of the
> less experienced among us, could you give a "30,000 meter" overview
> of how the methodology you propose differs from that integrated in the
> DiscRack example?

This is actually a good comparison...if you look at Login.java in the DiscRack example (I'm using Enhydra 3.0.3, but I think it's close) it corrolates pretty well with the EventHandler example because functionally they're doing very similar things. So how are they different?

First of all, the discRack stuff extends from BasePO. BasePO uses what I call a psuedo-event methodology. If the URL contains an event=XXX parameter the BasePO tries to invoke handleXXX(), if not, it calls handleDefault(). On the plus side, this approach is pretty easy to understand. On the down side, it uses reflection (which is slow), but it also forces you into a 1:1 relationship between events and handlers...this works fine for simple apps, but gets difficult as the screen complexity because you end up with huge handlers which are not very reusable or componetized.

The Barracuda model converts incoming requests into actual events. Any number of handlers can listen for events (just like in a stated app), so if I need to do multiple things in response to a request, I just create multiple listeners. Each one can do one thing (and do it well). This increases reusability through high cohesion.

The Barracuda model also uses a built in Model 2 dispatching pattern. This allows listeners (Controllers) to handle the incoming request and then specify the appropriate view to be rendered by firing another event (whoever handles that corresponds to the View).

Not only does this provide further decoupling, it also provides a secure API -- people cannot just invoke any event handler in an app...they can only invoke request events, whose handlers in turn can determine whether or not they are authorized to do whatever they are requesting and route them on accordingly. Now granted, this is slightly more complex (two steps instead of one), however, it seems to be quite a bit more scalable and reusable.

Now let's look at some really interesting features of the Barracuda event model approach. HttpRequestEvents (the only thing served through an HTTP gateway) implement a marker interface called Polymorphic. When a polymorphic event is dispatched, all of it's parent events are dispatched first (because it _is an instance_ of those events).

For instance, in the Barracuda example, we have an event hierarchy that looks something like this:

  • DefaultBaseEvent
    • HttpRequestEvent (implements Polymorphic)
      • ...
      • LoginScreenEvent
        • GetLoginScreenEvent
        • AttemptLoginEvent
      • MainScreenEvent
        • GetMainScreenEvent
    • HttpResponseEvent (implements Exceptional)
      • ...
      • RenderEvent
        • RenderLoginScreenEvent
        • RenderMainScreenEvent
      • ErrorEvent
        • ...

When the event dispatcher goes to dispatch the GetLoginScreenEvent, it first dispatches parent events: HttpRequestEvent, and LoginScreenEvent. This allows us to install "global" listeners on entire portions of the system.

For instance, in the sample app, whenever someone fires an event that is NOT an instance of LoginScreenEvent, we want to first make sure they're already validated. If someone fires some kind of LoginScreenEvent and they are already validated, I can easily redirect them to Main screen by simply marking the event queue as handled and firing a new GetMainScreenEvent.

The key thing to note here is that the individual handlers only need to know about their particular domain (ie. getting the actual screen, attempting to login in, etc). They do not need to know about the special rules that tie everything all together. In typical approaches (like the BasePO) all this logic is tightly coupled in one place. With an event driven approach it can easily be decoupled (and hence more easily reused).

Another feature of the event dispatching in Barracuda is what we call Exceptional behavior. When an event implements the Exceptional interface (notice all HttpResponseEvents do so), if that event is not handled the dispatcher automatically fires the parent event, (which propogates up the chain until someone handles it, just like with Exceptions).

This is _very_ useful with error handling. Let's say you want to install a default error page in a system. Just add a listener on ErrorEvent, and no matter how many error classes get added to the system, you are always guaranteed to catch it. And if you want to add more specialized error messages for a particular type of error, you just create a specific Error Event for that situation and install a listener for that particular event. It is very flexible.

Here's another example. Let's say you want to add some kind of logging for just _part_ of the system, perhaps screens 1,2, and 3, but NOT 4. It's very easy to modify the event hierarchy so that screen events 1,2 and 3 all extend from a common event class. Add a listener for that type of event and your in business. Again, this facilitates loose coupling and reuse. And it doesn't have any impact on existing event listeners.

Perhaps the most valuable aspect of the Barracuda event oriented approach is that it sets us up for creating servers side components which could be bound to portions of an XMLC class. Want to set data in a complex XMLC list or table? Just grab the object's Model and program against it (just like in Swing). Want to be notified when someone presses a button? Just add an event listener for that particular component. When the action is invoked on the client side it gets routed back to your handler code automatically. This is where this stuff is going...

The biggest drawback to event oriented programming is you have to think a little harder about how you want to organize your system hierarchically. I tend to start by identifying the basic screens in the system. For each screen, what are the possible requests? responses? errors? How do I organize these hierarchically?

Once I have the event hierarchy defined, then it's fairly easy to start adding event handlers for "leaf" events (those at the end of the hierarchy). Then I go back and add handlers for events further up in the hierarchy, establishing the system flow. Once you get the basic idea, it's actually very straightforward. It allows you to create a working system very early on and then gradually flesh out the functionality. It's easy to integrate with XMLC, and it performs very efficiently.

One of the things I'd like to do fairly soon is create a "NewBarracudaApp" utility/wizard to streamline this whole thing and automate a lot of the mundane aspects. This would make it really easy to sit down and create a working Barracuda app in no time.

For all the latest information on Barracuda, please refer to http://barracudamvc.org
Questions, comments, feedback? Let us know...