Well, thanks everyone for your responses, especially Slava - although I have
to admit to not quite following the metaphor. I guess supermarkets in
Australia operate differently?
But, seriously, after digesting the comments of all invovled and also having
completed some more of the system design, I am leaning back towards separate
classes for each web action. I have rationlised the number of separate web
actions required to a more manageable number.
I was however, a little confused by some of the comments against web actions
mapping to a designated class and method. I was not planning to have
different parameter lists on these methods, just the normal
HttpServletRequest and HttpServletResponse, the same as with the command
pattern action( ) method Craig spoke of. And I was generally not planning
on storing these beans in the session, but caching them at the application
scope. So as I see it, the only practical difference is the extra
complexity of using Reflection techniques to invoke the dynamic method name,
instead of the well-known method name in the Command interface.
However, I believe there is something to be said for avoiding complexity if
you don't need it. And as I am leaving this employer shortly, implementing
a commonly used design pattern that is more likely to be understood by
future developers is also desirable.
Regards
Drew
> -----Original Message-----
> From: Slava Kozlov [SMTP:[EMAIL PROTECTED]]
> Sent: Thursday, January 13, 2000 5:19 AM
> To: [EMAIL PROTECTED]
> Subject: Re: How to dispatch web actions from servlet to dynamically
> namedbea nclass.method ?
>
> > -----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
===========================================================================
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