struts-dev mailing list archives

Site index · List index
Message view « Date » · « Thread »
Top « Date » · « Thread »
From "PILGRIM, Peter, FM" <Peter.PILG...@rbos.com>
Subject RE: composable RequestProcessor
Date Tue, 03 Jun 2003 09:01:16 GMT

> -----Original Message-----
> From: Matthias Bauer [mailto:Matthias.Bauer@livinglogic.de]
> 
> 
> I am very much in line with you. Where do we go from now? It 
> would be a 
> pity if we let the ideas drain, we discussed here.
> 
> --- Matthias
> 
> 
> Andrew Hill wrote:
> 
> ><snip>
> >This leads to a proliferation of classes.  The standard Java 
> way of dealing
> >with large interfaces it to provide an Adapter class that people can
> >subclass and override the few methods they need.
> ></snip>
> >
> >I can see how your worried that we will end up with a 
> truckload of classes -
> >and we certainly will end up with a lot more interfaces 
> (<drool/>) (might be
> >an idea to have a requestprocessor package!) but I still 
> reckon your missing
> >the point mate.
> >
> >The idea is to be able to break out the different bits of RP 
> functionality
> >into different classes that you can plug in to customise 
> that specific
> >process *if necessary*. Now these dont HAVE to be different 
> classes, but the
> >idea is to allow them to be if you have to so that your not 
> stuck with the
> >current situation of one big uberProcessor that is a take it 
> or leave it
> >proposition (well ok, so you can subclass it of course, but 
> that doesnt
> >really make life easy if you also need to subclass another 
> one for other
> >bits of the functionality).
> >

If you are going to break out the different methods of the RP
in to separate interfaces, then consider if some of the
method e.g `process*' can be grouped together. Hence
we reduce the number of interfaces.

Just looking at the Javadoc for the request processor
interface reveals some sub processor groupings:

interface ActionRequestProcessorInterface {

    Action processActionCreate( javax.servlet.http.HttpServletRequest
request, 
	
javax.servlet.http.HttpServletResponse response, 
					ActionMapping mapping) ;

    ActionForm processActionForm(javax.servlet.http.HttpServletRequest
request, javax.servlet.http.HttpServletResponse response, ActionMapping
mapping) ;

    ActionForward processActionPerform(javax.servlet.http.HttpServletRequest
request, 
			javax.servlet.http.HttpServletResponse response, 
			Action action, 
			ActionForm form, ActionMapping mapping) ;

    

}

interface DispatchRequestProcessorInterface {

    void doForward(java.lang.String uri, 
		javax.servlet.http.HttpServletRequest request,
		 javax.servlet.http.HttpServletResponse response) ;

    void doInclude(java.lang.String uri, 
		javax.servlet.http.HttpServletRequest request, 
		javax.servlet.http.HttpServletResponse response) 
}

> >Id say most of the time you would - as now - use the standard request
> >processor that comes with struts *however* you can 
> specifically override
> >certain bits of it to do what you need. You can do this now 
> of course, but
> >the difference in the multiple interface approach is that 
> Joe User can take
> >the processXXX class from struts extension FOO and the 
> processYYY class from
> >extension BAR and use them together without having to 
> analyse the source and
> >write his own third class to unite the two in some kind of 
> dodgy shotgun
> >marraige.

Would grouping the interfaces as I have done above actually
solve this problem? If you have two request processor
that implemented my `DispatchRequestProcessorInterface '
as above you would still have the same messy aggregation
problems as above, albeit is lesser number of methods
to consider. I am unsure if this is easier.

There is another question here, or couple.

By making a request processor an interface you pass on
the concrete details, the actual whereabouts of the 
data attributes and the other object instance data 
members to some other class X out there. 

If you look at the javadoc for the default `RequestProcessor'
it has a list collection of Action objects. This is a map collection
of all the actions that are configured via XML for this module config.
When you start delegating or aggregating request processors, you
must ask the question, in which controller has the module `Actions'.

For example

class AcmeRequestProcessor extends RequestProcessor
implements RequestProcessorInterface 
{
    
     RequestProcessorInterface  tiles = new TilesRequestProcessor();
    
     public void whereAreMyActions( ) {

	// Which is the correct collection actions 
	// for this module config?
	this.actions.get("/Login.do" );
	// or 
	tiles.getAction().get("/Login.do" );

}

I think we have NOT been considering the data members of the
current default controller (RP).

New accessor and mutators would be required, as I hinted with
the ``Map getActions()'' call above.

May be this is a "separation of concerns" design. The multiple 
interface no longer sounds right, especially with the data 
members. I am starting think there could be performance
problems if we start delegating calls ad infinitum too.

May be the question is "what is a request processor?"


> >
> >(Obviously if both need to override processXXX then there 
> are going be some
> >problems (unless XXX is something that ALSO happens to be amenable to
> >chaining) but based on the comments from other people Id 
> reckon this is rare
> >enough to come into the 20 rather than the 80 (for those who 
> believe in the
> >80/20 rule))
> >
> >-----Original Message-----
> >From: David Graham [mailto:dgraham1980@hotmail.com]
> >Sent: Monday, 2 June 2003 22:41
> >To: andrew.david.hill@gridnode.com; struts-dev@jakarta.apache.org
> >Subject: RE: composable RequestProcessor
> >
> >
> >  
> >
> >>Well I see little point in defining an interface that 
> simply requires you
> >>to
> >>implement all the hooks in the RP.
> >>It doesnt seem to get us any further than where we are 
> already (well apart
> >>    
> >>
> >>from satisfying my compulsive desires for more interfaces!)
> >  
> >
> >>You need to break it out into multiple discrete interfaces 
> so you can do
> >>something like:
> >>
> >>public class BobRequestSubprocessor implements RoleProcessor,
> >>ActionFormProcessor
> >>{
> >>  public void processRole(...) {
> >>    ...
> >>  }
> >>
> >>  public ActionForm processActionForm(...) {
> >>    ...
> >>  }
> >>}
> >>
> >>Then you can specify a class for each individual processXXX in your
> >>struts-config , and of course the main requestprocessor 
> class itself which
> >>implements the lot and is used as a 'default' where a more 
> specific handler
> >>is not specified...
> >>    
> >>
> >
> >This leads to a proliferation of classes.  The standard Java 
> way of dealing
> >with large interfaces it to provide an Adapter class that people can
> >subclass and override the few methods they need.
> >
> >David
> >
> >
> >  
> >
> >>But I still havent thought of a nice way to resolve 'conflicts'.
> >>For example you have the FOO and the BAR extensions written 
> by different
> >>people and for the sake of example, both need to override 
> something like
> >>processActionForm() ... is a generic way of handling this a 
> possibility?
> >>This sort of method isnt conceptually amenable to chaining 
> as it has to
> >>return a single value, and yet both extensions RPs need to 
> do their own
> >>thing here. I guess that sort of method simply has to have 
> specific code
> >>that is written to unite the two RPs , such as what MB has 
> had to do to
> >>marry workflow and tiles under the current architecture...
> >>
> >>-----Original Message-----
> >>From: David Graham [mailto:dgraham1980@hotmail.com]
> >>Sent: Monday, 2 June 2003 22:12
> >>To: struts-dev@jakarta.apache.org
> >>Subject: RE: composable RequestProcessor
> >>
> >>
> >>    
> >>
> >>>An interface should be easy to construct aggregated 
> request processors.
> >>>If you are saying
> >>>
> >>>import org.apache.struts.mythical.RequestProcessorInterface;
> >>>
> >>>class FooRequestProcessor implements RequestProcessorInterface
> >>>{
> >>>    RequestProcessInterface   tiles = new TilesRequestProcessor();
> >>>    RequestProcessInterface   jndi = new JndiRequestProcessor();
> >>>
> >>>    public Action doForward( ... ) {
> >>>	return tiles.doForward( ... );
> >>>    }
> >>>
> >>>    public void processRole( ... ) {
> >>>      jndi.processRole(...);
> >>>    }
> >>>
> >>>    public void processRole( ... ) {
> >>>      jndi.processRole(...);
> >>>    }
> >>>
> >>>    public void processBoth( ... ) {  // Invented method!!
> >>>      jndi.processBoth(...);
> >>>      tiles.processBoth(...);
> >>>    }
> >>>}
> >>>      
> >>>
> >>That's exactly what I had in mind.
> >>

Actually when I think about it, what I wrote originally was not
quite correct.

class FooRequestProcessor extends RequestProcessor
implements RequestProcessorInterface 
{

    ....
}

The `Foo' controller extends the default one. So in the end
you end up with a kind of a splayed delegation class.

--////--

--
Peter Pilgrim,
Struts/J2EE Consultant, RBoS FM, Risk IT
Tel: +44 (0)207-375-4923



***********************************************************************
      Visit our Internet site at http://www.rbsmarkets.com

This e-mail is intended only for the addressee named above.
As this e-mail may contain confidential or privileged information,
if you are not the named addressee, you are not authorised to
retain, read, copy or disseminate this message or any part of it.
The Royal Bank of Scotland plc is registered in Scotland No 90312
Registered Office: 36 St Andrew Square, Edinburgh EH2 2YB 
Regulated by the Financial Services Authority
***********************************************************************

---------------------------------------------------------------------
To unsubscribe, e-mail: struts-dev-unsubscribe@jakarta.apache.org
For additional commands, e-mail: struts-dev-help@jakarta.apache.org


Mime
View raw message