The problem I see when I review applications is that people are already
writing spaghetti code. They create dynamic forwards, pasting on
parameters, and so forth, building up an package of arcane 
instuctions, just so they can turn around and have those parsed 
back into an ActionForm someplace else. 

If someone wants to chain an action, this lets them do so cleanly
without infesting the action class with all the HTTP parameters the
ActionForms work so hard to strip out :)

Bypassing the semantics is actually the point, since the Struts
request/forward cycle has side effects like resetting and refreshing
the ActionForm from the request. 

There are workarounds, like adding a switch to make an ActionForm
immutable, but it really seems to me that, in practice, keeping one
action from invoking another promotes spaghetti code, rather than
preventing it. Creating an ActionForward to send control around the
mulberry bush is not as clear as simply invoking the Action you want.

Personally, I do * not * chain Actions. I put the functionality in a
business API that various Actions can call if they need to. But I see a
lot of people trying to chain Actions, and this seemed like a cleaner
alternative than hardcoding HTTP details, like parameters, into the
Actions. It's not a perfect solution but HTTP is not a perfect protocol.

Again, I strongly feel that the better alternative is to use the Actions
like macros to call a business API, but it's like pulling teeth to get
people to do that =:0( And this seems like the next best thing. 

Of course, it would not be hard to just put this in an optional package,
like Scaffold, since I understand the importance of not encouraging
incorrect behavior, * so that's what I will plan on doing *, and we 
can ldave it out of the cannonical ActionServlet. But it is important 
to recognize that the approach we have now does not really
encourage correct behavior either. At least in practice.

Hopefully, the workflow model * will * encourage better behavior, since
that encourages use of a business API rather than casting Actions in
that role. I've been doing a lot of workflow-type things in my own
applications lately, which I think will map well to the Commons
initiative. It's gotten so I rarely write a new custom action anymore,
but simply instruct a standard one to access business method, and return
the result. Everything is run from the Struts config, as you envisioned
in the original workflow proposal :)

-T.


"Craig R. McClanahan" wrote:
> Chaining is unlikely to be significantly more efficient than request
> dispatcher forwarding.  Also, beyond that, I do have a couple of
> design/architecture concerns:
> 
> * Not using a RequestDispatcher.forward() means you don't get
>   the container semantics of erasing any previously generated
>   output (and complaining if you've already committed the response).
>   Unless you simulate this -- which you could do with wrappers in
>   Servlet 2.3 -- an action invoked this way sees different behavior
>   than one invoked via an RD.
> 
> * In the early days of servlets (prior to the 2.0 spec) there was a
>   feature of some containers called "servlet chaining", which differs
>   in details from this but was the same idea in spirit -- seducing
>   the developer into combining components in ways that were not the
>   original intent.  People that used this technique tended to create
>   spaghetti code that was very difficult to maintain.  I'd rather
>   avoid that.
> 
> * Because using a request dispatcher flows back through the controller,
>   we have the opportunity to "value add" new standard logic (such as
>   role-based access)  before the forward is completed -- but chaining
>   would bypass this.
> 
> I vote for maintaining the original design intent, and requiring actions
> who want to invoke others to simply return an ActionForward that points at
> another action, instead of a UI component.
> 
> > Or, did you just want to deal with it later? Should I take care of it
> > now?
> >
> > -Ted.

--
To unsubscribe, e-mail:   <mailto:[EMAIL PROTECTED]>
For additional commands, e-mail: <mailto:[EMAIL PROTECTED]>

Reply via email to