This document attempt to provide a thorough, objective answer to the question of why we should convert HTTP Requests into true Event objects, rather than just distributing the request information as Strings.
One of the questions that seems to be coming up a lot is, "Why should we convert HTTP Requests to Event objects?"
The argument seems to run something like this:
"Why should we convert HTTP Requests to Event objects? After all, when we do so, we still have to pass along the HTTP Request and Response objects, so the event listener can get at the parameter information that accompanied the request. Why not just pass all this information to listeners as String values? We could still deliver the same information to subscribed listeners either way. Passing the information as Strings would save the costs of object instantiation, so why not go that route instead?"
I think this is a valid question that we need to be able to answer... there are several ways we can address the issue.
J2EE already gives one answer in the J2EE Blueprint (see pages p21-23, 68-69, 254-297). In a nutshell, they recommend converting requests to events as soon as possible so that services which handle the events can be used both for web-apps and for EJB type services (ie reusability).
I think this is a valid argument, but I suspect it may not resonate with a lot of developers because J2EE is not for everyone. In other words, how many web-app developers are actually out there building systems that are large enough to have a web-app interface AND a J2EE interface? I'm sure ther are some, but I doubt they constitute the majority of web-app development yet.
I think there are other reasons though, which I'd consider more compelling for typically web-app developers.
Strong Typing - Registering listeners for events by a String name means you won't catch errors until runtime. That makes it harder to debug. For instance, I much prefer
eb.addEventListener(listenerFactory, TestEvent.class);
over
eb.addEventListener(listenerFactory, "blah.foo,.TestEvent.class");
They are both functionally equivalent (if you go and
look inside the event broker, it is converting the class name to a
String value and storing it). The difference is, the first one is
checked at compile time -- see the "," in the second example? That
wouldn't get caught until runtime, and even then it wouldn't get noticed
until a user or test case noticed that the event wasn't getting handled
as expected.
Encapsulation - Let's say I have an
HTTP event which is accompanied by certain parameters. If I have 100
different listeners, if a parameter name changes, then I have to go make
changes in 100 different places. If the event had been encapsulated in
an object, I'd only have to make the change in one place.
Now, lets say an http request changes to no longer use a
particular parameter. If I was using real events, I simply remove that
property from the event (and the methods to access it), and when I
recompile the whole system I will catch every single reference to that
property. In other words, the system won't compile until I've fixed all
the outdated references to it. This is really another example of the
strong typing benefits you give up with a string based approach.
Inheritance & Hierarchy - Along the
lines of the previous example...By using true events objects to form an
inheritance heirarchy of events, you can access properties/functionality
defined the parent classes. This also makes it possible to adopt
"exception oriented" dispatching policies, whereby unhandled events
would have parent events thrown.
Now, I'm not trying to argue that this is necessarily
what we _should_ do, just that without using true objects that define
heirarchy, we are much more limited in what we _can_ do. There is no way
to do "inheritance" or "heirarchy" if your events just consist of a set
of string parameters.
Polymorphism - It would also be
possible to build events that implement other interfaces. For instance,
maybe instead of distinguishing between BaseEvents and WebEvents the way
we do now, perhaps there should just be one type of root "Event", which
could optionally implement "WebEvent" (indicating it carries special
HTTP information, and requires a response) or "SNMPEvent" (indicating it
originated from SNMP and needs information sent back in that protocol)
or perhaps we could even use polymorphism to distinguish between what
visual format the response should follow (HTML vs. WML vs. XML). I
haven't fully explored the polymorphistic potential for events, but it
certainly offers some very interesting possibilities.
Internal Consistency - Few people
question the value of having a real object model for server-generated
events. However, If you have "web events" which are essentially routed
based on String names and "server events" which are generated on the
server and routed as true event objects, I'd much prefer a consistant
approach to both of them...after all they are both "events". If you
don't want to do this, then you really need 2 event models--one for Web
Events and one for all other events. I think that's much more difficult
and complicated.
Paradigm Consistency - This is a weaker argument than the previous one, but I think it's still valid. I would argue that existing Event models in other domains typically don't just invoke listeners--they pass in a reference to the event that triggered the invocation. This allows you to distinguish between different instances of the same event. Now, you could accomplish the same thing by just examining string params from the HTTP req, but why not follow the more familiar model? In other words, if we're going to build an event model for web-apps, why not build one that looks as close as possible to existing event models for stated apps (where they've already proven their worth).
I think there are probably more arguments for this position, but I'd like to shift gears and take a different tack. Given the well-known advantages of object-oriented methodologies, I think the burden of proof should fall on those who want to use strings instead of objects. In other words, I think a better question to ask is "Why _shouldn't_ we use objects to represent events?"
I can only think of 2 arguments that are even reasonably compelling.
Performance Implications - If we can
demonstrate that there is a significant performance impact associated
with converting requests to events, then perhaps we have a case.
However, I really don't think it's there. The slowest part of a
transaction is generally the HTTP connect/disconnect overhead, followed
by the time required to access database and persistant storage. As
initial performance testing has indicated, even instantiating the events
through reflection does not carry a tremendous penalty, and what little
there is can be offset by a pooling mechanism.
Nobody else does it this way - It could
also be argued that "Nobody else uses events, so we shouldn't either.
After all, developers are more familiar with the types of approaches
that are already out there. They're used to handling strings in a web
app environment..."
Hmmm. I'd offer three responses.
First of all, we can look to client-side development and see that event oriented approaches are well established there (ie. Swing, EJB, etc).
Secondly, we can look at docs like the J2EE Blueprint and see that other folks in the industry are starting to recognize the value of this same fundamental approach on the server side (if anything, moving to an true "object" event model sets developers up for an easy transition to J2EE, something we should be touting).
Third, I'd assert that it's the very _lack_ of robust event model approaches that have really hindered the growth and development of presentation frameworks on the server side. When you look at what's out there in comparison with client-side models, it's pretty meager. I'd argue that part of that is from not approaching the problem from an event-centric perspective.
In conclusion, I think that we can make a conclusive argument for converting HTTP Requests to true Event objects. Ultimately, however, it's you the developers who have to buy into this. I'd be very interested in hearing whether you find these arguments compelling, and why or why not.