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.
- The Question
- The J2EE Answer
- My Answers
- A Better Question
- In Conclusion
The Question
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.
The J2EE Answer...
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.
My Answers...
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 & Heirarchy - 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).
A Better Question...
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
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.
Please email me with your comments. |