> -----Original Message-----
> From: A mailing list about Java Server Pages specification and reference
> [mailto:[EMAIL PROTECTED]]On Behalf Of Craig R. McClanahan
> Sent: Wednesday, January 12, 2000 10:53 AM
> To: [EMAIL PROTECTED]
> Subject: Re: How to dispatch web actions from servlet to dynamically
> namedbea nclass.method ?
>
>
> Daniel Lopez wrote:
>
> > Hi Drew,
> >
> > What you ask for shouldn't be too difficult to implement. If I had to do
> > it, I'd use reflection, as you mentioned, and I'd just add a new field
> > in configuration file to allow the user to specify the name of the
> > method to be called. However, if you want the methods to be executed
> > using one instance, then you should also add something to identify the
> > instance you want to use for every operation. If you wanted to call
> > methods that have parameters things could get much more cumbersome.
> >
>
> It isn't actually that bad. The Java Reflection API lets you
> dynamically select a
> method name, and set up a list of arguments in an array. You do,
> however, have to
> know how many arguments to send (and what types they are), which
> leads to the next
> comment.
>
> >
> > On the other hand... do you think it is really necessary to call
> > different methods in the same class?. If you store the bean in the
> > session( or in servlet context) and each operations is a small class
> > that gets the parameters and calls the appropriate method from that
> > shared bean, things get easier and, IMHO, more cleanly separated.
> > As you pointed out, this Bean that you keep between calls inside the
> > same user session, fits pretty much into the definition of a session
> > EJB.
> >
> > As I conclusion, I'll just say that I opted for the command pattern
> > because it keeps the controller servlet, and the configuration file,
> > simpler and because I prefer to have a set of simple classes that
> > perform each one a simple operation than one, or more classes, that
> > implement everything. I find this arrangement easier to understand,
> > debug, and easier to work with, when you develop in group. But that's a
> > matter of taste.
> >
>
> I chose exactly the same approach (all my commands are
> independent Action classes
> that implement an Action.perform(HttpServletRequest req,
> HttpServletResponse res)
> method. I made this choice for the same reasons that Dan
> articulated (boy, we
> must be pretty smart :-). To avoid class creation overhead, I
> cache an instance
> of each Action class the first time it is used, and just re-use
> the same instance
> over and over again for subsequent requests to the same command.
> Now, I can code
> my action classes totally independently of each other, and be
> pretty confident
> there's no side effects from multithreading or other factors.
>
> >
> > Just my 2c,
> > Dan
>
> Craig McClanahan
Oh, I'll give my 2 cents on the design issue as well.
If I may metaphorize: the difference between having one class with lots of
web action methods and a collection of classes each specialized in their own
function is the difference between going to supermarket with one blanket
'deli' section with a single type of person handling all the various foods
and going to a high-service supermarket (like say Balducci's here in NYC)
which has specialized service folks to help you with each of your needs -
cheese, meat, fish, coffee, pastry, bread, flowers, etc. The service is much
better because the service folks can hone their knowledge. (Having multiple
service people at one deli counter is simply an analogy for
multithreadedness - more people, not more specialization. And you still have
to manage common resources for synchronization, like that single wheel of
Chaubier.)
Back out of the metaphor. Other reasons for an atomic Action architecture:
1) More lifecycle support. Not only can one do the web action - one can have
more fine-grained control over the lifecycle of a web action. A typical
Action interface/lifecycle may be:
init - initialize action resources and configure web action
execute* - do the action
log - log that the action has been performed (usually in a
specialized
way)
release - release resources
Depending on your needs/design you could also:
- distill configuration out of the init sequence to enable dynamic
reconfiguration.
- add access checking (does the user have permission to execute this
action?)
- group actions into "activities" (got to love English with its similar
words with different nuances of meaning. :)
(Or better yet: add these as augmenting interfaces.)
*Avoid linguistic debate over whether "do", "perform" or "execute" is the
best name to connote the handle by which the Action will be called to
do/execute/perfom/act its function. :-) Also no debate over whether the name
of the interface is Action or Command or Task or Function.
2) Take advantage of object-orientation:
- allows for hierarchies of Action classes. It's important not to get
carried away with inheritance but there are certainly times when it's
remarkably elegant. As an example, take a SearchAction class which searches
in a db according to a couple typical fields. It can be extended with a
PowerSearchAction which is able to distinguish more fields - or maybe checks
for common spelling problems (whatever). Depending on how modular/templated
the original SearchAction class was, one may need to only change a couple
methods - say, the form_db_query method.
- a collection of action classes is more modular than methods in a single
class; you can for example, add an action to the list by simply creating a
new class (and configuring), without recompiling the code for all the other
actions; you don't even need the code for any of the other actions.
- create complex Actions dynamically. A couple generic compound Action
classes - a LogicalAndAction which executes all its subactions, and a
LogicalOrAction which stops after the first successful one - let's one build
complex actions out of simple ones simply by tooling around with the config
file.
Couple other notes:
- I wouldn't store the bean in the session - in the supermarket analogy,
equivalent to creating/hiring a new cheese guy for every customer that walks
in the door and buys cheese :-).
I'd say that the web actions aren't user-specific - you'll have multiple
users trying to do the same thing. I'd put the action beans into a registrar
of some sort (a Map will do - though a typesafe subclass of Map will do
better). And put the registrar into the servlet (you may only need one
servlet class now!) or into the servlet context depending on your other
design needs.
- Parameters. The main advantage of the multiplemethod technique is that you
can have specific argument signatures for each method (though one still has
to check for the correct number, etc). With a uniform Action interface, you
need a uniform execute method - the solution is to have a generic Parameter
class, which is what HttpRequest is (although it does a few more things
too). For other design reasons, I like wrapping an HttpRequest in an
ActionRequest object and passing that to the Action objects ....
- Performance. I haven't checked it but it seems to me that a simple lookup
in a Map should be faster than doing Java Reflection. At the very least it
certainly shouldn't be slower (maybe the JVM is smart enough to cache
subsequent Reflection lookups, but that would be a map too!).
BTW, I'll be chauvanistic and say it's more than just "a matter of taste"
(Daniel Lopez's words above) to create modular, testable and debuggable
software; it's part of the job description (at least mine). But that's just
an opinion. :-)
-s
Slava Kozlov (not the RedWings' hockey player :-)
===========================================================================
To unsubscribe: mailto [EMAIL PROTECTED] with body: "signoff JSP-INTEREST".
FAQs on JSP can be found at:
http://java.sun.com/products/jsp/faq.html
http://www.esperanto.org.nz/jsp/jspfaq.html