struts-dev mailing list archives

Site index · List index
Message view « Date » · « Thread »
Top « Date » · « Thread »
From "Craig R. McClanahan" <craig...@apache.org>
Subject Re: About exntensions support mechanism...
Date Sat, 07 Jul 2001 20:37:37 GMT
Several intermixed comments, plus some general notes at the bottom ...

On 5 Jul 2001, Roland Huss wrote:

> Oleg V Alexeev <gonza@penza.net> writes:
> 
> >   ServiceServlet work on idea - developer can register unlimited
> >   number of services in struts-config, each service is a java class
> >   based on Service interface, each service can be subscribed to any
> >   processing point, such as - init, destroy, initDigester,
> >   processPreprocess, processPopulateBefore, processPopulateAfter,
> >   processValidateBefore, processValidateAfter. ServiceServlet iterate
> >   via list of subscriptions at every processing point and call
> >   appropriate method from service.
> 
> Instead of a "Service" _interface_ I suggest a a Service base class
> with no-op implementations for the plugin hooks. This would make a
> possible late upgrade of the plugin contract much easier, since it
> won't break existing code.
> 

+1, *especially* if you use the "hard coded" registration
approach.  Otherwise, you'll break every Service implementation in the
world when you add a new registration hook.  This is why ActionForm is a
base class rather than an interface.

An intermediate solution would be to define Service as an interface and
ServiceBase (or something) as a convenience base class that most people
would use.  That way, you only impact those who directly implement Service
themselves.

> >   My question is - what way is the best to serve processing points
> >   listed above? Now I create FastArrayList instances for every
> >   subscription list and all manipulations with subscriptions
> >   (register, get iterator via subscriptions, drop, etc.) are made with
> >   help of separate method -
> >   
> >    registerInitMember( Service service, int order ) {}
> >    regisetrInitDigesterMember( Service service, int order ) {}
> >    ....
> > 
> >   May be such solution would be more flexible? -
> >    registerMember( Service service, int order, String pointName ) {
> >          //find ArrayList of subscriptions for such pointName
> >          //register service at ArrayList
> >    }
> > 
> >   Hard coded solution is more reliable, but time consume and not
> >   flexible. But more flexible solution, with search for appropriate
> >   subscription, is slow for my mind. What way is the best?
> 

Both patterns are common in JavaBeans APIs, but I tend to slightly prefer
the "hard coded" approach myself.  Among other things, it eliminates the
chance to have typos in your pointName values, leading to "why didn't my
service get invoked?" kinds of questions.

Do you really need an "order" argument, though?  If we guaranteed that
services would be invoked in the order that they are listed in the
struts-config.xml file, that would seem to give people the control they
need.

> I think the first solution is more preferable, since you have only one
> kind of plugin defined by one interface (or base class).
> 
> If you would like to differentiate between different kind of plugins
> different kind of interfaces (or base classes) like InitService and
> ProcessService might provide the extra flexibility to selectively call
> only the appropriate plugin at certain hooks (and a plugin only needs
> to implement the service interface (extend service base class) it is
> interested in. (Well, in this scenario, interfaces are probably better
> suited than base classes, since a plugin could implement several
> interfaces at once but not extend more than one base class).
> 

On a more general note, there is a "services framework" type thing in
several other projects, notably in Turbine and Cocoon (and
Jetspeed?).  Can we leverage/learn anything from those efforts?  Is there
any opportunity to abstract out common requirements in a
framework-independent manner that could be shared (perhaps as a Commons
project)?

Craig


Mime
View raw message