I'm sorry to bring back up a discussion that's been hashed out already, but there's something I still don't understand...
I can see why it's better for every command in the chain to be executed rather than executing a "sub-chain" based on some condition. I can see the correlation of the sub-chain idea to the goto notion.
But this leaves some baggage that I'm still not comfortable with. Now every command after ValidateActionForm has to know about the "validKey" attribute. So far, that's ok. At least I can readily see the chain of execution and there's no variation in it. But, what if I introduce a command of my own that creates some conditions? Now do I have to customize *every* command in the chain after mine just to check for my condition? This also makes it difficult at best to change the order of execution if I so desired, but I don't know if that's necessarily a bad thing.
If this is the case, how are we any better off with this model than we were with a monolithic request processor? Why should the commands have so much inter-dependence now that they are separate objects? Are we better off with them as inter-dependent separate objects than we were as one monolithic object?
Now, is there any way to get the best of both worlds -- no gotos, and no "state baggage"? Is it possible that the command could just be responsible for executing and not ever be called unless all the conditions are in place for it to be executed? Something at a higher level than the command would have to determine whether it should be executed? So, you might have something between the chain and the command that determines that. I'm not sure if that's any better because then *that* component would have to know about all the commands as well.....
Anyway, I hope I'm making sense. I hate to ask a question and then leave the room, but I'll have to take answers in the morning :-)
If you've got tightly connected commands that are already highly interdependent (and a chain for replacing RequestProcessor definitely fits this description), there is normally so much shared state information already that adding tests for conditions isn't going to add any coupling that wasn't present already. If you're wiring together commands that are loosely coupled, and don't necessarily want the commands to know about each other's state, you're probably better off doing the "branch to an alternate chain" trick, based on a decision in a command that implements the branch.
Both styles do work, and (in fact) both are still employed in the chain-config.xml right now:
* The "servlet-complete" chain selects the appropriate sub-application module and branches, giving you the opportunity to plug in per-module chains that are completely different and independent, without introducing any coupling other than placing the ModuleConfig in the right place (i.e. the "servlet-standard" chain expects that as a precondition, instead of loading the ModuleConfig at the beginning of its own work).
* The "servlet-standard" chain is mostly synchronous, but still has a branch for exception handling (required, in this case, because it's not caught until the postprocess() method, meaning that the rest of the chain has already been executed and someone threw an exception).
For any given chain, pick the style that makes the most sense for your use case. But, while we're still experimenting, I tend to play with lots of fine-grained chains that are glued together by "smart" commands that branch based on conditions, and then look later to see if there is enough shared state to collapse those chains into one.
CraigThanks, Greg
--------------------------------------------------------------------- To unsubscribe, e-mail: [EMAIL PROTECTED] For additional commands, e-mail: [EMAIL PROTECTED]